From 58f563424c6b4ce30ffb020cedccf643c95fd325 Mon Sep 17 00:00:00 2001 From: M0Rf30 Date: Mon, 28 Feb 2022 12:37:47 +0100 Subject: [PATCH] chore(package): bump to 1.4.2 --- .github/workflows/main.yml | 91 +- .gitignore | 4 + README.md | 8 +- cie-java/build.gradle | 8 +- .../src/main/com/ugos/crypt/hash/SHA1.java | 4 +- cie-java/src/main/it/ipzs/cieid/Logger.java | 112 + .../src/main/it/ipzs/cieid/MainFrame.java | 765 ++- .../src/main/it/ipzs/cieid/Middleware.java | 6 +- libcie-pkcs11/CSP/AbilitaCIE.cpp | 201 +- libcie-pkcs11/CSP/ExtAuthKey.cpp | 46 +- libcie-pkcs11/CSP/FirmaConCIE.cpp | 37 +- libcie-pkcs11/CSP/IAS.cpp | 3220 ++++++------ libcie-pkcs11/CSP/PINManager.cpp | 70 +- libcie-pkcs11/CSP/VerificaConCIE.cpp | 5 +- libcie-pkcs11/Crypto/AES.cpp | 238 +- libcie-pkcs11/Crypto/ASNParser.cpp | 478 +- libcie-pkcs11/Crypto/DES3.cpp | 332 +- libcie-pkcs11/Crypto/MAC.cpp | 270 +- libcie-pkcs11/Crypto/MD5.cpp | 168 +- libcie-pkcs11/Crypto/RSA.cpp | 372 +- libcie-pkcs11/Crypto/SHA1.cpp | 172 +- libcie-pkcs11/Crypto/SHA256.cpp | 152 +- libcie-pkcs11/LOGGER/Logger.cpp | 414 ++ libcie-pkcs11/LOGGER/Logger.h | 117 + libcie-pkcs11/PCSC/APDU.cpp | 122 +- libcie-pkcs11/PCSC/CardLocker.cpp | 60 +- libcie-pkcs11/PCSC/PCSC.cpp | 322 +- libcie-pkcs11/PCSC/Token.cpp | 278 +- libcie-pkcs11/PKCS11/CIEP11Template.cpp | 1544 +++--- libcie-pkcs11/PKCS11/CardContext.cpp | 136 +- libcie-pkcs11/PKCS11/CardTemplate.cpp | 248 +- libcie-pkcs11/PKCS11/Mechanism.cpp | 1962 ++++---- libcie-pkcs11/PKCS11/P11Object.cpp | 326 +- libcie-pkcs11/PKCS11/PKCS11Functions.cpp | 4369 +++++++++-------- libcie-pkcs11/PKCS11/PKCS11Functions.h | 148 +- libcie-pkcs11/PKCS11/Slot.cpp | 1402 +++--- libcie-pkcs11/PKCS11/initP11.cpp | 20 +- libcie-pkcs11/PKCS11/session.cpp | 2803 +++++------ libcie-pkcs11/Sign/CIESign.cpp | 266 +- libcie-pkcs11/Sign/CIEVerify.cpp | 253 +- libcie-pkcs11/Util/Array.cpp | 694 +-- libcie-pkcs11/Util/Array.h | 2 - libcie-pkcs11/Util/CacheLib.cpp | 754 +-- libcie-pkcs11/Util/IniSettings.cpp | 274 +- libcie-pkcs11/Util/ModuleInfo.cpp | 68 +- libcie-pkcs11/Util/SyncroEvent.cpp | 34 +- libcie-pkcs11/Util/TLV.cpp | 220 +- libcie-pkcs11/Util/UUCByteArray.cpp | 642 +-- libcie-pkcs11/Util/UUCProperties.cpp | 336 +- libcie-pkcs11/Util/UUCStringTable.cpp | 232 +- libcie-pkcs11/Util/UUCTextFileReader.cpp | 224 +- libcie-pkcs11/Util/UtilException.cpp | 4 +- libcie-pkcs11/Util/funccallinfo.cpp | 97 +- libcie-pkcs11/Util/log.cpp | 998 ++-- libcie-pkcs11/Util/util.cpp | 1247 ++--- libcie-pkcs11/meson.build | 6 +- packages/cie-middleware/PKGBUILD | 21 +- 57 files changed, 14232 insertions(+), 13170 deletions(-) create mode 100644 cie-java/src/main/it/ipzs/cieid/Logger.java create mode 100644 libcie-pkcs11/LOGGER/Logger.cpp create mode 100644 libcie-pkcs11/LOGGER/Logger.h diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3afaf61d..574b3f3b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -6,76 +6,47 @@ name: CI on: # Triggers the workflow on push or pull request events but only for the main branch push: - branches: - - "*" - tags: - - 1.* pull_request: - branches: [ main ] - tags: - - 1.* - + # Allows you to run this workflow manually from the Actions tab workflow_dispatch: # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: # This workflow contains a single job called "build" - build: - # The type of runner that the job will run on - runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job + gradle: + strategy: + matrix: + os: [ubuntu-latest] + runs-on: ${{ matrix.os }} steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v2 + - uses: actions/setup-java@v2 + with: + distribution: temurin + java-version: 11 - # Runs a set of commands using the runners shell - - name: Build - run: | - cd packages - docker run -v $(pwd):/project packagefoundation/yap-ubuntu-bionic:latest build ubuntu-bionic . - for i in $(ls artifacts/); do sha256sum artifacts/$i >> SHA256SUMS; done - - - name: version - run: echo "::set-output name=version::$(cat packages/cie-middleware/PKGBUILD | grep pkgver | cut -d\" -f2)" - id: version + - name: Setup Gradle + uses: gradle/gradle-build-action@v2 - # - name: release - # uses: actions/create-release@v1 - # id: create_release - # with: - # draft: false - # prerelease: false - # release_name: ${{ steps.version.outputs.version }} - # tag_name: ${{ github.ref }} - # env: - # GITHUB_TOKEN: ${{ github.token }} - # - name: upload deb artifact - # uses: actions/upload-release-asset@v1 - # env: - # GITHUB_TOKEN: ${{ github.token }} - # with: - # upload_url: ${{ steps.create_release.outputs.upload_url }} - # asset_path: packages/artifacts - # asset_name: cie-middleware_1.4.2-0ubuntu1_amd64.deb - # asset_content_type: application/vnd.debian.binary-package - # - name: upload SHA - # uses: actions/upload-release-asset@v1 - # env: - # GITHUB_TOKEN: ${{ github.token }} - # with: - # upload_url: ${{ steps.create_release.outputs.upload_url }} - # asset_path: packages/SHA256SUMS - # asset_name: SHA256SUMS - # asset_content_type: application/text + - name: Execute Gradle build + run: | + gradle -b cie-java/build.gradle standalone + + - name: Install Dependencies + run: sudo apt install -y g++ libpcsclite-dev openjdk-11-jre-headless libssl-dev pkg-config python3-pip unzip libcrypto++-dev libcrypto++6 libpcsclite1 libssl1.1 pcscd - - name: Archive production artifacts - uses: actions/upload-artifact@v2 + - uses: actions/setup-python@v1 + with: + python-version: '3.x' + - run: pip install meson ninja + env: + CC: gcc + - run: meson builddir libcie-pkcs11 + - run: meson configure -Dprefix=/usr builddir + - run: meson compile -C builddir + - uses: actions/upload-artifact@v1 + if: failure() with: - name: dist - path: | - packages/artifacts/*.deb - packages/artifacts/*.rpm - packages/artifacts/*.zst - packages/SHA256SUMS + name: Linux_Meson_Testlog + path: builddir/meson-logs/testlog.txt \ No newline at end of file diff --git a/.gitignore b/.gitignore index 76c6a694..eacee573 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ *.VC.opendb /cie-java/.gradle /cie-java/bin +*.a *.o *.d *.so @@ -16,3 +17,6 @@ gradle/ .idea/ gradlew gradlew.bat +.trunk +build/ +builddir/ diff --git a/README.md b/README.md index eef309ac..aa41ceec 100644 --- a/README.md +++ b/README.md @@ -60,8 +60,8 @@ distro GNU/Linux: ### Prerequisiti -Fare riferimento al file [pacur/PKGBUILD](pacur/PKGBUILD) per ottenere le -dipendenze di build-time and run-time per la propria distribuzione. +Fare riferimento al file [PKGBUILD](packages/cie-middleware/PKGBUILD) per +ottenere le dipendenze di build-time and run-time per la propria distribuzione. È inoltre possibile trovare le istruzioni complete per costruire gli artefatti necessari e specifici per la propria distro. @@ -72,8 +72,8 @@ Da terminale, spostarsi nella root del presente repo e digitare: ```sh gradle -b cie-java/build.gradle standalone -cd libcie-pkcs11/ -meson builddir + +meson builddir libcie-pkcs11/ meson configure -Dprefix=/usr builddir meson compile -C builddir ``` diff --git a/cie-java/build.gradle b/cie-java/build.gradle index f5226240..63901a21 100644 --- a/cie-java/build.gradle +++ b/cie-java/build.gradle @@ -4,7 +4,7 @@ plugins { // Apply the application plugin to add support for building a CLI application. id 'application' - id "com.diffplug.spotless" version "6.0.0" + id "com.diffplug.spotless" version "6.3.0" } repositories { @@ -23,7 +23,7 @@ spotless { } java { // apply a specific flavor of google-java-format - googleJavaFormat('1.8').aosp() + googleJavaFormat('1.14.0').aosp() } } @@ -36,13 +36,13 @@ dependencies { implementation 'com.dorkbox:ShellExecutor:1.1' implementation 'com.dorkbox:SystemTray:4.1' implementation 'com.dorkbox:TweenEngine:8.3' - implementation 'com.google.code.gson:gson:2.8.9' + implementation 'com.google.code.gson:gson:2.9.0' implementation 'com.jgoodies:jgoodies-forms:1.9.0' implementation 'net.java.dev.jna:jna:5.9.0' implementation 'net.java.dev.jna:jna-platform:5.9.0' implementation 'org.ghost4j:ghost4j:1.0.1' implementation 'org.javassist:javassist:3.28.0-GA' - implementation 'org.slf4j:slf4j-api:1.7.32' + implementation 'org.slf4j:slf4j-api:1.7.36' } application { diff --git a/cie-java/src/main/com/ugos/crypt/hash/SHA1.java b/cie-java/src/main/com/ugos/crypt/hash/SHA1.java index 80114d98..cb40f16b 100644 --- a/cie-java/src/main/com/ugos/crypt/hash/SHA1.java +++ b/cie-java/src/main/com/ugos/crypt/hash/SHA1.java @@ -1,6 +1,8 @@ package com.ugos.crypt.hash; -/** @author Ugo Chirico Customized and ported on J2ME */ +/** + * @author Ugo Chirico Customized and ported on J2ME + */ public final class SHA1 { // Length of the final hash (in bytes). private static final int HASH_LENGTH = 20; diff --git a/cie-java/src/main/it/ipzs/cieid/Logger.java b/cie-java/src/main/it/ipzs/cieid/Logger.java new file mode 100644 index 00000000..406faab1 --- /dev/null +++ b/cie-java/src/main/it/ipzs/cieid/Logger.java @@ -0,0 +1,112 @@ +package it.ipzs.cieid; + +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; + +public class Logger { + + public enum LogLevel { + NONE, + DEBUG, + INFO, + ERROR; + + public static Logger.LogLevel getLevelFromInteger(Integer value) { + LogLevel logLevel = Logger.defaultLogLevel; + switch (value) { + case 0: + logLevel = NONE; + break; + case 1: + logLevel = DEBUG; + break; + case 2: + logLevel = INFO; + break; + case 3: + logLevel = ERROR; + break; + default: + throw new IllegalArgumentException("Integer value out of range"); + } + return logLevel; + } + } + + public static LogLevel defaultLogLevel = LogLevel.ERROR; + + private LogLevel level; + private static Logger Instance; + + private Logger() {} + + private Logger(LogLevel logLevel) { + setLevel(logLevel); + } + + private void Log(String message, LogLevel messageLevel) { + if (level.compareTo(LogLevel.NONE) > 0 && (level.compareTo(messageLevel) <= 0)) { + Write(message); + } + } + + private void Write(String message) { + OffsetDateTime currentOffsetDateTime = OffsetDateTime.now(ZoneOffset.UTC); + + String currentDate = currentOffsetDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE); + String logFileName = String.format("CIEID_%s.log", currentDate); + Path logFilePath = Paths.get(System.getProperty("user.home"), ".CIEPKI", logFileName); + + String currentTimestamp = + currentOffsetDateTime.format( + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")); + String timestampedMessage = String.format("%s %s\n", currentTimestamp, message); + + try { + Files.write( + logFilePath, + timestampedMessage.getBytes(StandardCharsets.UTF_8), + StandardOpenOption.APPEND, + StandardOpenOption.CREATE); + } catch (Exception exception) { + System.out.print("Exception at Logger.Write() - message: " + timestampedMessage); + } + } + + public static Logger getInstance() { + return getInstance(defaultLogLevel); + } + + public static Logger getInstance(LogLevel logLevel) { + if (Instance == null) { + Instance = new Logger(logLevel); + } + return Instance; + } + + public void Debug(String message) { + Log(String.format("[D] %s", message), LogLevel.DEBUG); + } + + public void Info(String message) { + Log(String.format("[I] %s", message), LogLevel.INFO); + } + + public void Error(String message) { + Log(String.format("[E] %s", message), LogLevel.ERROR); + } + + public void setLevel(LogLevel level) { + this.level = level; + } + + public LogLevel getLevel() { + return this.level; + } +} diff --git a/cie-java/src/main/it/ipzs/cieid/MainFrame.java b/cie-java/src/main/it/ipzs/cieid/MainFrame.java index f50c47dd..2814efd7 100644 --- a/cie-java/src/main/it/ipzs/cieid/MainFrame.java +++ b/cie-java/src/main/it/ipzs/cieid/MainFrame.java @@ -7,10 +7,12 @@ import it.ipzs.cieid.Firma.FileDrop; import it.ipzs.cieid.Firma.PdfPreview; import it.ipzs.cieid.Firma.VerifyTable; +import it.ipzs.cieid.Logger.LogLevel; import it.ipzs.cieid.Middleware.verifyInfo; import it.ipzs.cieid.util.Utils; import java.awt.CardLayout; import java.awt.Color; +import java.awt.Component; import java.awt.EventQueue; import java.awt.FlowLayout; import java.awt.Font; @@ -39,6 +41,7 @@ import java.nio.file.DirectoryNotEmptyException; import java.nio.file.Files; import java.nio.file.NoSuchFileException; +import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.HashMap; @@ -46,6 +49,9 @@ import java.util.Map; import javax.imageio.ImageIO; import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.ButtonGroup; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBox; @@ -56,6 +62,7 @@ import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JProgressBar; +import javax.swing.JRadioButton; import javax.swing.JScrollPane; import javax.swing.JTabbedPane; import javax.swing.JTextArea; @@ -63,6 +70,7 @@ import javax.swing.JTextPane; import javax.swing.SwingConstants; import javax.swing.border.EmptyBorder; +import javax.swing.border.TitledBorder; import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.text.SimpleAttributeSet; import javax.swing.text.StyleConstants; @@ -71,6 +79,10 @@ import org.apache.commons.io.FilenameUtils; public class MainFrame extends JFrame { + private final Logger logger; + private final LogLevelConfig logConfig; + private static final String LOG_CONFIG_PREFIX_APP = "APP_LOG_LEVEL"; + private static final String LOG_CONFIG_PREFIX_LIB = "LIB_LOG_LEVEL"; public static final int CKR_OK = 0x00000000; public static final int CKR_CANCEL = 0x00000001; @@ -282,10 +294,10 @@ public class MainFrame extends JFrame { private final JButton btnProseguiOp; private final JButton btnCreaFirma; private final JPanel Impostazioni; - private final JLabel lblConfigProxy; - private final JPanel panel_33; + private final JLabel lblConfigProxyTitle; + private final JPanel configProxyBodyPanel; private final JButton btnSalva; - private final JLabel lblNewLabel_14; + private final JLabel lblConfigProxyCaption; private final JTextField txtProxyAddr; private final JTextField txtUsername; private final JPasswordField txtPassword; @@ -294,6 +306,29 @@ public class MainFrame extends JFrame { private final JButton btnModificaProxy; private final JCheckBox chckbxMostraPassword; private final JButton btnEstrai; + private final JPanel configButtonsPanel; + private final Component verticalGlue; + private final Component verticalGlue_1; + private final Component verticalGlue_2; + private final Component verticalGlue_3; + private final Component verticalGlue_4; + private final Component verticalGlue_5; + private final Component verticalGlue_6; + private final Component verticalGlue_7; + private final Component verticalGlue_8; + private final Component verticalGlue_9; + private final JPanel panelConfigLoggingApp; + private final JPanel panelConfigLoggingLib; + private final JRadioButton rdbtnLoggingAppNone; + private final JRadioButton rdbtnLoggingAppError; + private final JRadioButton rdbtnLoggingAppInfo; + private final JRadioButton rdbtnLoggingAppDebug; + private final JRadioButton rdbtnLoggingLibError; + private final JRadioButton rdbtnLoggingLibInfo; + private final JRadioButton rdbtnLoggingLibDebug; + private final JRadioButton rdbtnLoggingLibNone; + private final ButtonGroup buttonGroupLoggingApp = new ButtonGroup(); + private final ButtonGroup buttonGroupLoggingLib = new ButtonGroup(); private enum SignOp { OP_NONE, @@ -301,6 +336,20 @@ private enum SignOp { CADES } + public class LogLevelConfig { + private LogLevel app; + private LogLevel lib; + + public LogLevelConfig() { + this(Logger.defaultLogLevel, Logger.defaultLogLevel); + } + + public LogLevelConfig(LogLevel appLevel, LogLevel libLevel) { + this.app = appLevel; + this.lib = libLevel; + } + } + /** Launch the application. */ public static void main(final String[] args) { EventQueue.invokeLater( @@ -318,6 +367,11 @@ public void run() { /** Create the frame. */ public MainFrame(String[] args) { + logger = Logger.getInstance(); + logConfig = new LogLevelConfig(); + LoadLogConfigFromFile(); + logger.Info("Inizializza frame principale"); + signOperation = SignOp.OP_NONE; setResizable(false); setBackground(Color.WHITE); @@ -357,6 +411,7 @@ public MainFrame(String[] args) { btnHome.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { + logger.Info("Inizia 'Home'"); selectButton(btnHome); selectHome(); } @@ -374,6 +429,7 @@ public void actionPerformed(ActionEvent e) { btnCambiaPin.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { + logger.Info("Inizia 'Cambia PIN'"); selectButton(btnCambiaPin); oldpin.setText(""); newpin1.setText(""); @@ -393,6 +449,7 @@ public void actionPerformed(ActionEvent e) { btnSbloccaCarta.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { + logger.Info("Inizia 'Sblocca Carta'"); selectButton(btnSbloccaCarta); pin01.setText(""); pin02.setText(""); @@ -412,6 +469,7 @@ public void actionPerformed(ActionEvent e) { btnTutorial.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { + logger.Info("Inizia 'Tutorial'"); selectButton(btnTutorial); tabbedPane.setSelectedIndex(7); } @@ -428,6 +486,7 @@ public void actionPerformed(ActionEvent e) { btnAiuto.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { + logger.Info("Inizia 'Aiuto'"); selectButton(btnAiuto); tabbedPane.setSelectedIndex(8); } @@ -444,6 +503,7 @@ public void actionPerformed(ActionEvent e) { btnInformazioni.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { + logger.Info("Inizia 'Informazioni'"); selectButton(btnInformazioni); tabbedPane.setSelectedIndex(9); } @@ -460,6 +520,7 @@ public void actionPerformed(ActionEvent e) { btnFirma.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { + logger.Info("Inizia 'Firma Elettronica'"); selectButton(btnFirma); @@ -520,22 +581,11 @@ public void actionPerformed(ActionEvent e) { btnImpostazioni.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent arg0) { - - btnModificaProxy.setEnabled(false); - - if (Utils.getProperty("proxyURL", "").equals("")) { - txtProxyAddr.setEnabled(true); - txtUsername.setEnabled(true); - txtPassword.setEnabled(true); - txtPorta.setEnabled(true); - chckbxMostraPassword.setEnabled(true); - chckbxMostraPassword.setSelected(false); - btnSalva.setEnabled(true); - btnModificaProxy.setEnabled(false); - - selectButton(btnImpostazioni); - tabbedPane.setSelectedIndex(17); - } else { + logger.Info("Inizia 'Impostazioni'"); + LoadLogConfigFromFile(); + disableConfigurationPaneControls(); + if (!Utils.getProperty("proxyURL", "").equals("")) { + logger.Debug(" Impostazione proxy presente"); if (Utils.getProperty("credentials", "").equals("")) { txtPassword.setText(""); txtUsername.setText(""); @@ -553,19 +603,20 @@ public void actionPerformed(ActionEvent arg0) { txtProxyAddr.setText(Utils.getProperty("proxyURL", "")); txtPorta.setText(Utils.getProperty("proxyPort", "")); - - txtProxyAddr.setEnabled(false); - txtUsername.setEnabled(false); - txtPassword.setEnabled(false); - txtPorta.setEnabled(false); - chckbxMostraPassword.setEnabled(false); - chckbxMostraPassword.setSelected(false); - btnSalva.setEnabled(false); - btnModificaProxy.setEnabled(true); - - selectButton(btnImpostazioni); - tabbedPane.setSelectedIndex(17); } + + rdbtnLoggingAppNone.setSelected(logConfig.app.equals(LogLevel.NONE)); + rdbtnLoggingAppDebug.setSelected(logConfig.app.equals(LogLevel.DEBUG)); + rdbtnLoggingAppInfo.setSelected(logConfig.app.equals(LogLevel.INFO)); + rdbtnLoggingAppError.setSelected(logConfig.app.equals(LogLevel.ERROR)); + + rdbtnLoggingLibNone.setSelected(logConfig.lib.equals(LogLevel.NONE)); + rdbtnLoggingLibDebug.setSelected(logConfig.lib.equals(LogLevel.DEBUG)); + rdbtnLoggingLibInfo.setSelected(logConfig.lib.equals(LogLevel.INFO)); + rdbtnLoggingLibError.setSelected(logConfig.lib.equals(LogLevel.ERROR)); + + selectButton(btnImpostazioni); + tabbedPane.setSelectedIndex(17); } }); btnImpostazioni.setIcon( @@ -613,6 +664,7 @@ public void actionPerformed(ActionEvent arg0) { btnAbbina.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { + logger.Info("Inizia 'Abbina'"); abbinaCIE(); } @@ -782,10 +834,10 @@ public void keyTyped(KeyEvent e) { buttonsPanel.setBounds(133, 500, 384, 36); btnAnnulla = new JButton("Annulla"); - btnAnnulla.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { + logger.Info("Annulla abbinamento carta"); selectHome(); } }); @@ -869,65 +921,67 @@ public void actionPerformed(ActionEvent e) { btnPanel.setBackground(Color.WHITE); btnRemoveAll = new JButton("Rimuovi tutte"); - btnRemoveAll.setForeground(Color.WHITE); - btnRemoveAll.setBackground(new Color(30, 144, 255)); btnRemoveAll.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { + logger.Info("Inizia Rimozione tutte le carte abbinate"); List cieList = new ArrayList(cieDictionary.values()); disabilitaAllCIE(cieList); } }); + btnRemoveAll.setForeground(Color.WHITE); + btnRemoveAll.setBackground(new Color(30, 144, 255)); btnPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 20, 5)); btnPanel.add(btnRemoveAll); btnRemoveSelected = new JButton("Rimuovi carta selezionata"); - btnRemoveSelected.setForeground(Color.WHITE); - btnRemoveSelected.setBackground(new Color(30, 144, 255)); btnRemoveSelected.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { + logger.Info("Inizia 'Rimuovi carta selezionata'"); Cie cieToDelete = cieCarousel.getCardAtIndex(); disabilitaCIE(cieToDelete.getPan(), cieToDelete.getName()); } }); + btnRemoveSelected.setForeground(Color.WHITE); + btnRemoveSelected.setBackground(new Color(30, 144, 255)); btnPanel.add(btnRemoveSelected); btnNewButton = new JButton("Aggiungi carta"); - btnNewButton.setForeground(Color.WHITE); - btnNewButton.setBackground(new Color(30, 144, 255)); btnNewButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { + logger.Info("Inizia 'Aggiungi carta'"); tabbedPane.setSelectedIndex(0); // abbinaCIE(); } }); + btnNewButton.setForeground(Color.WHITE); + btnNewButton.setBackground(new Color(30, 144, 255)); btnPanel.add(btnNewButton); panel_3.add(btnPanel); btnSelezionaCIE = new JButton("Seleziona"); - btnSelezionaCIE.setForeground(Color.WHITE); - btnSelezionaCIE.setBackground(new Color(30, 144, 255)); - btnSelezionaCIE.setVisible(false); - btnSelezionaCIE.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { + logger.Info("Inizia 'Seleziona'"); CieCard selectedCIE = getSelectedCIE(); if (selectedCIE.getCard().getIsCustomSign()) { + logger.Debug("Firma personalizzata presente"); lblPersonalizza.setText("Aggiorna"); lblHint.setText( "Un tua firma personalizzata è già stata caricata. Vuoi aggiornarla?"); lblFPOK.setVisible(true); lblSFP.setVisible(false); } else { + logger.Debug("Firma personalizzata assente - crea firma default"); lblPersonalizza.setText("Personalizza"); lblHint.setText( "Abbiamo creato per te una firma grafica, ma se preferisci puo personalizzarla. " @@ -939,6 +993,9 @@ public void actionPerformed(ActionEvent e) { tabbedPane.setSelectedIndex(10); } }); + btnSelezionaCIE.setForeground(Color.WHITE); + btnSelezionaCIE.setBackground(new Color(30, 144, 255)); + btnSelezionaCIE.setVisible(false); btnPanel.add(btnSelezionaCIE); lblCieId = new JLabel("CIE ID"); @@ -990,6 +1047,7 @@ public void actionPerformed(ActionEvent e) { btnDoCambiaPin.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { + logger.Info("Inizia 'Cambia PIN'"); cambiaPIN(); } }); @@ -1136,6 +1194,7 @@ public void keyTyped(KeyEvent e) { btnSblocca.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { + logger.Info("Inizia 'Sblocca'"); sbloccaPIN(); } }); @@ -1386,6 +1445,7 @@ public void filesDropped(java.io.File[] files) { btnSelezionaUnDocumento.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { + logger.Info("Inizia 'Seleziona un documento'"); JFileChooser fileChooser = new JFileChooser(); int returnValue = fileChooser.showOpenDialog(null); if (returnValue == JFileChooser.APPROVE_OPTION) { @@ -1600,6 +1660,7 @@ public void run() { if (ret == 0) { int nSign = Middleware.INSTANCE.getNumberOfSign(); if (nSign == 0) { + logger.Info("Verifica completata"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "Il file selezionato non contiene firme", @@ -1622,13 +1683,14 @@ public void run() { verificaScrollPane.repaint(); - btnEstrai.setEnabled( - FilenameUtils.getExtension(filePath) - .equals("p7m")); + btnEstrai.setEnabled(FilenameUtils.getExtension(filePath) + .equals("p7m")); tabbedPane.setSelectedIndex(16); } } else if (ret == (long) INVALID_FILE_TYPE) { + logger.Error( + "Il file selezionato non è un file valido"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "Il file selezionato non è un file valido. E' possibile verificare solo file con estensione .p7m o .pdf", @@ -1636,6 +1698,7 @@ public void run() { JOptionPane.ERROR_MESSAGE); tabbedPane.setSelectedIndex(10); } else { + logger.Error("Errore generico durante la verifica"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "Si è verificato un errore durante la verifica", @@ -1705,11 +1768,10 @@ public void mouseClicked(MouseEvent e) { "/it/ipzs/cieid/res/Firma/Coppia file firma.png"))); btnAnnullaOp = new JButton("Annulla"); - btnAnnullaOp.setBounds(147, 392, 136, 23); - panel_16.add(btnAnnullaOp); btnAnnullaOp.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { + logger.Info("Inizia 'Annulla'"); imgP7m.setIcon( new ImageIcon( MainFrame.class.getResource( @@ -1730,6 +1792,8 @@ public void actionPerformed(ActionEvent e) { tabbedPane.setSelectedIndex(10); } }); + btnAnnullaOp.setBounds(147, 392, 136, 23); + panel_16.add(btnAnnullaOp); btnAnnullaOp.setForeground(Color.WHITE); btnAnnullaOp.setBackground(new Color(30, 144, 255)); @@ -1925,6 +1989,7 @@ public void mouseEntered(MouseEvent e) { btnAnnullaOp_1.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { + logger.Info("Inizia 'Annulla'"); imgP7m.setIcon( new ImageIcon( MainFrame.class.getResource( @@ -1953,6 +2018,7 @@ public void actionPerformed(ActionEvent e) { btnProseguiOp.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { + logger.Info("Inizia 'PROSEGUI'"); for (int i = 0; i < passwordSignFields.length; i++) { JPasswordField field = passwordSignFields[i]; field.setText(""); @@ -2264,6 +2330,7 @@ public void mouseClicked(MouseEvent arg0) { btnConcludiFirma.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent arg0) { + logger.Info("Inizia 'Concludi'"); progressFirmaPin.setVisible(false); lblProgressFirmaPin.setText("Inserisci le ultime 4 cifre del pin"); @@ -2442,10 +2509,10 @@ public void keyTyped(KeyEvent e) { panel_30.add(panel_31); panel_31.setLayout(null); JButton btnSelectImg = new JButton("Seleziona un file"); - btnSelectImg.setFont(new Font("Dialog", Font.BOLD, 11)); btnSelectImg.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { + logger.Info("Inizia 'Seleziona un file'"); JFileChooser fileChooser = new JFileChooser(); FileNameExtensionFilter filter = new FileNameExtensionFilter("Png file", "png", "PNG"); @@ -2491,6 +2558,7 @@ public void actionPerformed(ActionEvent e) { btnCreaFirma.setEnabled(true); } catch (IOException er) { + logger.Error("Errore nel caricamento della firma personalizzata"); er.printStackTrace(); lblFirmaPersonalizzata.setText( "Errore nel caricamento della firma personalizzata"); @@ -2498,6 +2566,7 @@ public void actionPerformed(ActionEvent e) { } } }); + btnSelectImg.setFont(new Font("Dialog", Font.BOLD, 11)); btnSelectImg.setBounds(149, 0, 151, 23); panel_31.add(btnSelectImg); btnSelectImg.setForeground(Color.WHITE); @@ -2507,6 +2576,7 @@ public void actionPerformed(ActionEvent e) { btnAnnullaOp_6.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent arg0) { + logger.Info("Inizia 'Indietro'"); tabbedPane.setSelectedIndex(10); } }); @@ -2519,6 +2589,7 @@ public void actionPerformed(ActionEvent arg0) { btnCreaFirma.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent arg0) { + logger.Info("Inizia 'Crea firma'"); CieCard selectedCie = getSelectedCIE(); @@ -2655,8 +2726,8 @@ public void actionPerformed(ActionEvent arg0) { btnConcludiVerifica = new JButton("Concludi"); btnConcludiVerifica.addActionListener( new ActionListener() { - public void actionPerformed(ActionEvent arg0) { + logger.Info("Inizia 'Concludi'"); tabbedPane.setSelectedIndex(10); } }); @@ -2669,6 +2740,7 @@ public void actionPerformed(ActionEvent arg0) { btnEstrai.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent arg0) { + logger.Info("Inizia 'Estrai'"); String outfilePath = null; JFrame frame = new JFrame(); frame.setAlwaysOnTop(true); @@ -2708,7 +2780,7 @@ public void actionPerformed(ActionEvent arg0) { long ret = Middleware.INSTANCE.estraiP7m(filePath, outfilePath); if (ret != 0) { - + logger.Error("Impossibile estrarre il file"); JOptionPane.showMessageDialog( btnEstrai.getParent(), "Impossibile estrarre il file", @@ -2716,6 +2788,7 @@ public void actionPerformed(ActionEvent arg0) { JOptionPane.ERROR_MESSAGE); return; } else { + logger.Info("Estrazione completata"); JOptionPane.showMessageDialog( btnEstrai.getParent(), "File estratto correttamente", @@ -2737,133 +2810,67 @@ public void actionPerformed(ActionEvent arg0) { verifica.add(lblNewLabel_13); Impostazioni = new JPanel(); - Impostazioni.setLayout(null); Impostazioni.setBackground(Color.WHITE); tabbedPane.addTab("New tab", null, Impostazioni, null); + Impostazioni.setLayout(null); - lblConfigProxy = new JLabel("Configurazione server Proxy"); - lblConfigProxy.setHorizontalAlignment(SwingConstants.CENTER); - lblConfigProxy.setFont(new Font("Dialog", Font.BOLD, 28)); - lblConfigProxy.setBounds(65, 45, 471, 39); - Impostazioni.add(lblConfigProxy); - - panel_33 = new JPanel(); - panel_33.setLayout(null); - panel_33.setBackground(Color.WHITE); - panel_33.setBounds(76, 132, 449, 415); - Impostazioni.add(panel_33); - - btnSalva = new JButton("Salva"); - btnSalva.addActionListener( - new ActionListener() { - public void actionPerformed(ActionEvent arg0) { - - if ((txtUsername.getText().equals("") && !txtPassword.getText().equals("")) - || (!txtUsername.getText().equals("") - && txtPassword.getText().equals(""))) { - JOptionPane.showMessageDialog( - btnSalva.getParent(), - "Campo username o password mancante", - "Credenziali proxy mancanti", - JOptionPane.ERROR_MESSAGE); - return; - } - - if ((txtPorta.getText().equals("") && !txtProxyAddr.getText().equals("")) - || (!txtPorta.getText().equals("") - && txtProxyAddr.getText().equals(""))) { - JOptionPane.showMessageDialog( - btnSalva.getParent(), - "Indirizzo o porta del proxy mancante", - "Informazione proxy mancanti", - JOptionPane.ERROR_MESSAGE); - return; - } - - if (txtUsername.getText().equals("")) { - Utils.setProperty("credentials", ""); - } else { - String credentials = - String.format( - "cred=%s:%s", - txtUsername.getText(), txtPassword.getText()); - ProxyInfoManager proxyInfoManager = new ProxyInfoManager(); - String encryptedCredentials = proxyInfoManager.encrypt(credentials); - Utils.setProperty("credentials", encryptedCredentials); - } - - Utils.setProperty("proxyURL", txtProxyAddr.getText()); + JTabbedPane configTabbedPane = new JTabbedPane(JTabbedPane.TOP); + configTabbedPane.setBackground(Color.WHITE); + configTabbedPane.setBounds(12, 12, 571, 500); + Impostazioni.add(configTabbedPane); - if (txtPorta.getText() == "") { - Utils.setProperty("proxyPort", String.valueOf(0)); - } else { - Utils.setProperty("proxyPort", txtPorta.getText()); - } + JPanel configProxyPanel = new JPanel(); + configProxyPanel.setBackground(Color.WHITE); + configTabbedPane.addTab("Proxy", null, configProxyPanel, null); + configProxyPanel.setLayout(null); - txtProxyAddr.setEnabled(false); - txtUsername.setEnabled(false); - txtPassword.setEnabled(false); - txtPorta.setEnabled(false); - chckbxMostraPassword.setEnabled(false); - chckbxMostraPassword.setSelected(false); - btnSalva.setEnabled(false); - btnModificaProxy.setEnabled(true); - } - }); + lblConfigProxyTitle = new JLabel("Configurazione server Proxy"); + lblConfigProxyTitle.setBounds(67, 5, 450, 33); + configProxyPanel.add(lblConfigProxyTitle); + lblConfigProxyTitle.setHorizontalAlignment(SwingConstants.CENTER); + lblConfigProxyTitle.setFont(new Font("Dialog", Font.BOLD, 28)); - btnSalva.setForeground(Color.WHITE); - btnSalva.setBackground(new Color(30, 144, 255)); - btnSalva.setBounds(45, 392, 136, 23); - panel_33.add(btnSalva); + lblConfigProxyCaption = + new JLabel("Inserisci l'indirizzo del server proxy ed eventuali credenziali"); + lblConfigProxyCaption.setBounds(53, 43, 484, 18); + configProxyPanel.add(lblConfigProxyCaption); + lblConfigProxyCaption.setFont(new Font("Dialog", Font.BOLD, 15)); - btnModificaProxy = new JButton("Modifica"); - btnModificaProxy.addActionListener( - new ActionListener() { - public void actionPerformed(ActionEvent arg0) { - txtProxyAddr.setEnabled(true); - txtUsername.setEnabled(true); - txtPassword.setEnabled(true); - txtPorta.setEnabled(true); - chckbxMostraPassword.setEnabled(true); - chckbxMostraPassword.setSelected(false); - btnSalva.setEnabled(true); - btnModificaProxy.setEnabled(false); - } - }); - btnModificaProxy.setForeground(Color.WHITE); - btnModificaProxy.setBackground(new Color(30, 144, 255)); - btnModificaProxy.setBounds(271, 391, 136, 23); - panel_33.add(btnModificaProxy); + configProxyBodyPanel = new JPanel(); + configProxyBodyPanel.setBounds(37, 109, 500, 331); + configProxyPanel.add(configProxyBodyPanel); + configProxyBodyPanel.setLayout(null); + configProxyBodyPanel.setBackground(Color.WHITE); JLabel lblProxyAddr = new JLabel("Indirizzo (URL o indirizzo IP)"); lblProxyAddr.setHorizontalAlignment(SwingConstants.LEFT); lblProxyAddr.setFont(new Font("Dialog", Font.PLAIN, 14)); lblProxyAddr.setBounds(62, 95, 215, 23); - panel_33.add(lblProxyAddr); + configProxyBodyPanel.add(lblProxyAddr); txtProxyAddr = new JTextField(); txtProxyAddr.setBounds(62, 124, 234, 25); - panel_33.add(txtProxyAddr); + configProxyBodyPanel.add(txtProxyAddr); JLabel lblUsername = new JLabel("Username"); lblUsername.setHorizontalAlignment(SwingConstants.LEFT); lblUsername.setFont(new Font("Dialog", Font.PLAIN, 14)); lblUsername.setBounds(62, 160, 299, 36); - panel_33.add(lblUsername); + configProxyBodyPanel.add(lblUsername); txtUsername = new JTextField(); txtUsername.setBounds(62, 189, 234, 25); - panel_33.add(txtUsername); + configProxyBodyPanel.add(txtUsername); JLabel lblPassword = new JLabel("Password"); lblPassword.setHorizontalAlignment(SwingConstants.LEFT); lblPassword.setFont(new Font("Dialog", Font.PLAIN, 14)); lblPassword.setBounds(62, 226, 299, 36); - panel_33.add(lblPassword); + configProxyBodyPanel.add(lblPassword); txtPassword = new JPasswordField(); txtPassword.setBounds(62, 255, 234, 25); - panel_33.add(txtPassword); + configProxyBodyPanel.add(txtPassword); txtPorta = new JTextField(); @@ -2877,18 +2884,19 @@ public void keyTyped(KeyEvent evt) { }); txtPorta.setBounds(340, 124, 49, 25); - panel_33.add(txtPorta); + configProxyBodyPanel.add(txtPorta); JLabel lblPorta = new JLabel("Porta"); lblPorta.setHorizontalAlignment(SwingConstants.LEFT); lblPorta.setFont(new Font("Dialog", Font.PLAIN, 14)); lblPorta.setBounds(340, 95, 58, 23); - panel_33.add(lblPorta); + configProxyBodyPanel.add(lblPorta); chckbxMostraPassword = new JCheckBox("Mostra password"); chckbxMostraPassword.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { + logger.Info("Inizia 'Mostra password'"); if (chckbxMostraPassword.isSelected()) { txtPassword.setEchoChar((char) 0); } else { @@ -2899,13 +2907,229 @@ public void actionPerformed(ActionEvent e) { chckbxMostraPassword.setFont(new Font("Dialog", Font.BOLD, 10)); chckbxMostraPassword.setBackground(Color.WHITE); chckbxMostraPassword.setBounds(304, 256, 129, 23); - panel_33.add(chckbxMostraPassword); + configProxyBodyPanel.add(chckbxMostraPassword); + + JPanel configLoggingPanel = new JPanel(); + configLoggingPanel.setBackground(Color.WHITE); + configTabbedPane.addTab("Log", null, configLoggingPanel, null); + configLoggingPanel.setLayout(null); + + JLabel lblConfigLoggingTitle = new JLabel("Configurazione livello di log"); + lblConfigLoggingTitle.setBounds(73, 5, 444, 33); + lblConfigLoggingTitle.setHorizontalAlignment(SwingConstants.CENTER); + lblConfigLoggingTitle.setFont(new Font("Dialog", Font.BOLD, 28)); + configLoggingPanel.add(lblConfigLoggingTitle); + + JLabel lblConfigLoggingCaption = + new JLabel("Seleziona il livello desiderato per applicazione e libreria"); + lblConfigLoggingCaption.setBounds(69, 43, 446, 18); + lblConfigLoggingCaption.setFont(new Font("Dialog", Font.BOLD, 15)); + configLoggingPanel.add(lblConfigLoggingCaption); + + JPanel configLoggingBodyPanel = new JPanel(); + configLoggingBodyPanel.setBounds(37, 109, 500, 331); + configLoggingBodyPanel.setLayout(null); + configLoggingBodyPanel.setBackground(Color.WHITE); + configLoggingPanel.add(configLoggingBodyPanel); + + panelConfigLoggingApp = new JPanel(); + panelConfigLoggingApp.setBackground(Color.WHITE); + panelConfigLoggingApp.setBorder( + new TitledBorder( + null, + "Applicazione desktop", + TitledBorder.LEADING, + TitledBorder.TOP, + null, + null)); + panelConfigLoggingApp.setBounds(12, 12, 238, 307); + configLoggingBodyPanel.add(panelConfigLoggingApp); + panelConfigLoggingApp.setLayout(new BoxLayout(panelConfigLoggingApp, BoxLayout.Y_AXIS)); + + verticalGlue_5 = Box.createVerticalGlue(); + panelConfigLoggingApp.add(verticalGlue_5); + + rdbtnLoggingAppNone = new JRadioButton("None"); + buttonGroupLoggingApp.add(rdbtnLoggingAppNone); + rdbtnLoggingAppNone.setBackground(Color.WHITE); + rdbtnLoggingAppNone.setAlignmentX(Component.CENTER_ALIGNMENT); + panelConfigLoggingApp.add(rdbtnLoggingAppNone); + + verticalGlue_6 = Box.createVerticalGlue(); + panelConfigLoggingApp.add(verticalGlue_6); + + rdbtnLoggingAppDebug = new JRadioButton("Debug"); + buttonGroupLoggingApp.add(rdbtnLoggingAppDebug); + rdbtnLoggingAppDebug.setBackground(Color.WHITE); + rdbtnLoggingAppDebug.setAlignmentX(Component.CENTER_ALIGNMENT); + panelConfigLoggingApp.add(rdbtnLoggingAppDebug); + + verticalGlue_7 = Box.createVerticalGlue(); + panelConfigLoggingApp.add(verticalGlue_7); + + rdbtnLoggingAppInfo = new JRadioButton("Info"); + buttonGroupLoggingApp.add(rdbtnLoggingAppInfo); + rdbtnLoggingAppInfo.setBackground(Color.WHITE); + rdbtnLoggingAppInfo.setAlignmentX(Component.CENTER_ALIGNMENT); + panelConfigLoggingApp.add(rdbtnLoggingAppInfo); + + verticalGlue_8 = Box.createVerticalGlue(); + panelConfigLoggingApp.add(verticalGlue_8); + + rdbtnLoggingAppError = new JRadioButton("Error"); + buttonGroupLoggingApp.add(rdbtnLoggingAppError); + rdbtnLoggingAppError.setBackground(Color.WHITE); + rdbtnLoggingAppError.setAlignmentX(Component.CENTER_ALIGNMENT); + panelConfigLoggingApp.add(rdbtnLoggingAppError); + + verticalGlue_9 = Box.createVerticalGlue(); + panelConfigLoggingApp.add(verticalGlue_9); + + panelConfigLoggingLib = new JPanel(); + panelConfigLoggingLib.setBackground(Color.WHITE); + panelConfigLoggingLib.setBorder( + new TitledBorder( + null, "Libreria", TitledBorder.LEADING, TitledBorder.TOP, null, null)); + panelConfigLoggingLib.setBounds(252, 12, 238, 307); + configLoggingBodyPanel.add(panelConfigLoggingLib); + panelConfigLoggingLib.setLayout(new BoxLayout(panelConfigLoggingLib, BoxLayout.Y_AXIS)); + + verticalGlue = Box.createVerticalGlue(); + panelConfigLoggingLib.add(verticalGlue); + + rdbtnLoggingLibNone = new JRadioButton("None"); + buttonGroupLoggingLib.add(rdbtnLoggingLibNone); + rdbtnLoggingLibNone.setBackground(Color.WHITE); + rdbtnLoggingLibNone.setAlignmentX(Component.CENTER_ALIGNMENT); + panelConfigLoggingLib.add(rdbtnLoggingLibNone); + + verticalGlue_1 = Box.createVerticalGlue(); + panelConfigLoggingLib.add(verticalGlue_1); + + rdbtnLoggingLibDebug = new JRadioButton("Debug"); + buttonGroupLoggingLib.add(rdbtnLoggingLibDebug); + rdbtnLoggingLibDebug.setBackground(Color.WHITE); + rdbtnLoggingLibDebug.setAlignmentX(Component.CENTER_ALIGNMENT); + panelConfigLoggingLib.add(rdbtnLoggingLibDebug); + + verticalGlue_2 = Box.createVerticalGlue(); + panelConfigLoggingLib.add(verticalGlue_2); + + rdbtnLoggingLibInfo = new JRadioButton("Info"); + buttonGroupLoggingLib.add(rdbtnLoggingLibInfo); + rdbtnLoggingLibInfo.setBackground(Color.WHITE); + rdbtnLoggingLibInfo.setAlignmentX(Component.CENTER_ALIGNMENT); + panelConfigLoggingLib.add(rdbtnLoggingLibInfo); + + verticalGlue_3 = Box.createVerticalGlue(); + panelConfigLoggingLib.add(verticalGlue_3); + + rdbtnLoggingLibError = new JRadioButton("Error"); + buttonGroupLoggingLib.add(rdbtnLoggingLibError); + rdbtnLoggingLibError.setBackground(Color.WHITE); + rdbtnLoggingLibError.setAlignmentX(Component.CENTER_ALIGNMENT); + panelConfigLoggingLib.add(rdbtnLoggingLibError); + + verticalGlue_4 = Box.createVerticalGlue(); + panelConfigLoggingLib.add(verticalGlue_4); + + configButtonsPanel = new JPanel(); + configButtonsPanel.setBackground(Color.WHITE); + configButtonsPanel.setBounds(0, 524, 595, 47); + Impostazioni.add(configButtonsPanel); - lblNewLabel_14 = - new JLabel("Inserisci l'indirizzo del server proxy ed eventuali credenziali"); - lblNewLabel_14.setFont(new Font("Dialog", Font.BOLD, 15)); - lblNewLabel_14.setBounds(70, 82, 493, 15); - Impostazioni.add(lblNewLabel_14); + btnSalva = new JButton("Salva"); + btnSalva.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + logger.Info("Inizia 'Salva'"); + LogLevel logLevelAppValue = Logger.defaultLogLevel; + + if (rdbtnLoggingAppNone.isSelected()) { + logConfig.app = LogLevel.NONE; + logger.setLevel(LogLevel.NONE); + } else if (rdbtnLoggingAppDebug.isSelected()) { + logConfig.app = LogLevel.DEBUG; + logger.setLevel(LogLevel.DEBUG); + } else if (rdbtnLoggingAppInfo.isSelected()) { + logConfig.app = LogLevel.INFO; + logger.setLevel(LogLevel.INFO); + } else if (rdbtnLoggingAppError.isSelected()) { + logConfig.app = LogLevel.ERROR; + logger.setLevel(LogLevel.ERROR); + } + + if (rdbtnLoggingLibNone.isSelected()) { + logConfig.lib = LogLevel.NONE; + } else if (rdbtnLoggingLibDebug.isSelected()) { + logConfig.lib = LogLevel.DEBUG; + } else if (rdbtnLoggingLibInfo.isSelected()) { + logConfig.lib = LogLevel.INFO; + } else if (rdbtnLoggingLibError.isSelected()) { + logConfig.lib = LogLevel.ERROR; + } + + SaveLogConfigToFile(); + + if ((txtUsername.getText().equals("") && !txtPassword.getText().equals("")) + || (!txtUsername.getText().equals("") + && txtPassword.getText().equals(""))) { + JOptionPane.showMessageDialog( + btnSalva.getParent(), + "Campo username o password mancante", + "Credenziali proxy mancanti", + JOptionPane.ERROR_MESSAGE); + return; + } + + if ((txtPorta.getText().equals("") && !txtProxyAddr.getText().equals("")) + || (!txtPorta.getText().equals("") + && txtProxyAddr.getText().equals(""))) { + JOptionPane.showMessageDialog( + btnSalva.getParent(), + "Indirizzo o porta del proxy mancante", + "Informazione proxy mancanti", + JOptionPane.ERROR_MESSAGE); + return; + } + + if (txtUsername.getText().equals("")) { + Utils.setProperty("credentials", ""); + } else { + String credentials = + String.format( + "cred=%s:%s", + txtUsername.getText(), txtPassword.getText()); + ProxyInfoManager proxyInfoManager = new ProxyInfoManager(); + String encryptedCredentials = proxyInfoManager.encrypt(credentials); + Utils.setProperty("credentials", encryptedCredentials); + } + + Utils.setProperty("proxyURL", txtProxyAddr.getText()); + + if (txtPorta.getText() == "") { + Utils.setProperty("proxyPort", String.valueOf(0)); + } else { + Utils.setProperty("proxyPort", txtPorta.getText()); + } + disableConfigurationPaneControls(); + } + }); + btnSalva.setForeground(Color.WHITE); + btnSalva.setBackground(new Color(30, 144, 255)); + configButtonsPanel.add(btnSalva); + + btnModificaProxy = new JButton("Modifica"); + btnModificaProxy.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + logger.Info("Inizia 'Modifica'"); + enableConfigurationPaneControls(); + } + }); + btnModificaProxy.setForeground(Color.WHITE); + btnModificaProxy.setBackground(new Color(30, 144, 255)); + configButtonsPanel.add(btnModificaProxy); if (args.length > 0 && args[0].equals("unlock")) { selectUnlock(); @@ -2914,6 +3138,39 @@ public void actionPerformed(ActionEvent e) { } } + private void enableConfigurationPaneControls() { + logger.Info("Inizia - enableConfigurationPaneControls()"); + setConfigurationPaneControlsState(true); + } + + private void disableConfigurationPaneControls() { + logger.Info("Inizia - disableConfigurationPaneControls()"); + setConfigurationPaneControlsState(false); + } + + private void setConfigurationPaneControlsState(boolean value) { + txtProxyAddr.setEnabled(value); + txtUsername.setEnabled(value); + txtPassword.setEnabled(value); + txtPorta.setEnabled(value); + chckbxMostraPassword.setEnabled(value); + chckbxMostraPassword.setSelected(false); + btnSalva.setEnabled(value); + btnModificaProxy.setEnabled(!value); + + panelConfigLoggingApp.setEnabled(value); + rdbtnLoggingAppNone.setEnabled(value); + rdbtnLoggingAppDebug.setEnabled(value); + rdbtnLoggingAppInfo.setEnabled(value); + rdbtnLoggingAppError.setEnabled(value); + + panelConfigLoggingLib.setEnabled(value); + rdbtnLoggingLibNone.setEnabled(value); + rdbtnLoggingLibDebug.setEnabled(value); + rdbtnLoggingLibInfo.setEnabled(value); + rdbtnLoggingLibError.setEnabled(value); + } + private void selectButton(JButton button) { btnCambiaPin.setBackground(SystemColor.control); btnAiuto.setBackground(SystemColor.control); @@ -2956,11 +3213,11 @@ private void drawText(String text, String path) { text = toFirstCharUpperAll(toTitleCase(text).toLowerCase()); /* - System.out.println(MainFrame.class.getResource("/it/ipzs/cieid/res/Allura-Regular.ttf").toExternalForm()); + System.out.println(MainFrame.class.getResource("/it/ipzs/cieid/res/Allura-Regular.ttf").toExternalForm()); File file = new File(MainFrame.class.getResource("/it/ipzs/cieid/res/Allura-Regular.ttf").toExternalForm()); - //File file = new File("/usr/share/CIEID/cieid.jar/it/ipzs/cieid/res/Allura-Regular.ttf"); + //File file = new File("/usr/share/CIEID/cieid.jar/it/ipzs/cieid/res/Allura-Regular.ttf"); InputStream is = new FileInputStream(file); - */ + */ File file = null; String resource = "/it/ipzs/cieid/res/Allura-Regular.ttf"; @@ -2987,6 +3244,7 @@ private void drawText(String text, String path) { } if (file != null && !file.exists()) { + logger.Error(String.format("File '%s' non trovato", file)); throw new RuntimeException("Error: File " + file + " not found!"); } @@ -3021,6 +3279,7 @@ private void drawText(String text, String path) { } private void firma(String outFilePath) { + logger.Info("Inizia - firma()"); String pin = ""; @@ -3032,6 +3291,7 @@ private void firma(String outFilePath) { } if (pin.length() != 4) { + logger.Error("Il PIN deve essere composto dalle ultime 4 cifre - PIN non corretto"); JOptionPane.showMessageDialog( this.getContentPane(), "Il PIN deve essere composto dalle ultime 4 cifre", @@ -3048,6 +3308,7 @@ private void firma(String outFilePath) { } if (i < pin.length() || !(c >= '0' && c <= '9')) { + logger.Error("Il PIN deve essere composto dalle ultime 4 cifre - PIN non corretto"); JOptionPane.showMessageDialog( this.getContentPane(), "Il PIN deve essere composto dalle ultime 4 cifre", @@ -3106,7 +3367,9 @@ public void invoke(int retValue) { // TODO Auto-generated method stub System.out.println("Sign Completed!!"); + logger.Info("Firma completata"); if (retValue == 0) { + logger.Info("File firmato con successo"); lblEsitoFirma.setText("File firmato con successo"); imgEsitoFirma.setIcon( new ImageIcon( @@ -3114,6 +3377,8 @@ public void invoke(int retValue) { "/it/ipzs/cieid/res/Firma/check.png"))); } else { + logger.Error( + "Si è verificato un errore durante la firma"); lblEsitoFirma.setText( "Si è verificato un errore durante la firma"); imgEsitoFirma.setIcon( @@ -3202,6 +3467,8 @@ public void run() { switch (ret) { case CKR_TOKEN_NOT_RECOGNIZED: + logger.Error( + "Abilitazione CIE - CIE non presente sul lettore"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "CIE non presente sul lettore", @@ -3211,6 +3478,8 @@ public void run() { break; case CKR_TOKEN_NOT_PRESENT: + logger.Error( + "Abilitazione CIE - CIE non presente sul lettore"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "CIE non presente sul lettore", @@ -3220,6 +3489,10 @@ public void run() { break; case CKR_PIN_INCORRECT: + logger.Error( + String.format( + "Il PIN digitato è errato. rimangono %d tentativi", + attempts[0])); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), String.format( @@ -3231,6 +3504,7 @@ public void run() { break; case CKR_PIN_LOCKED: + logger.Error("Carta bloccata"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "Munisciti del codice PUK e utilizza la funzione di sblocco carta per abilitarla", @@ -3240,6 +3514,8 @@ public void run() { break; case CKR_GENERAL_ERROR: + logger.Error( + "Errore inaspettato durante la comunicazione con la smart card"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "Errore inaspettato durante la comunicazione con la smart card", @@ -3249,6 +3525,8 @@ public void run() { break; case CARD_PAN_MISMATCH: + logger.Error( + "CIE selezionata diversa da quella presente sul lettore"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "CIE selezionata diversa da quella presente sul lettore", @@ -3271,6 +3549,7 @@ public void run() { } private void showFirmaPin() { + logger.Info("Inizia - showFirmaPin()"); progressFirmaPin.setVisible(false); lblProgressFirmaPin.setText("Inserisci le ultime 4 cifre del pin"); @@ -3282,6 +3561,7 @@ private void showFirmaPin() { } private void abbinaCIE() { + logger.Info("Inizia - abbinaCIE()"); String pin = ""; int i; @@ -3292,6 +3572,7 @@ private void abbinaCIE() { } if (pin.length() != 8) { + logger.Error("PIN non corretto"); JOptionPane.showMessageDialog( this.getContentPane(), "Il PIN deve essere composto da 8 numeri", @@ -3308,6 +3589,7 @@ private void abbinaCIE() { } if (i < pin.length() || !(c >= '0' && c <= '9')) { + logger.Error("PIN non corretto"); JOptionPane.showMessageDialog( this.getContentPane(), "Il PIN deve essere composto da 8 numeri", @@ -3397,6 +3679,8 @@ public void run() { switch (ret) { case CKR_TOKEN_NOT_RECOGNIZED: + logger.Error( + "CIE non presente sul lettore"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "CIE non presente sul lettore", @@ -3407,6 +3691,8 @@ public void run() { break; case CKR_TOKEN_NOT_PRESENT: + logger.Error( + "CIE non presente sul lettore"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "CIE non presente sul lettore", @@ -3416,6 +3702,7 @@ public void run() { break; case CKR_PIN_INCORRECT: + logger.Error("PIN non corretto"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), String.format( @@ -3426,6 +3713,7 @@ public void run() { break; case CKR_PIN_LOCKED: + logger.Error("Carta bloccata"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "Munisciti del codice PUK e utilizza la funzione di sblocco carta per abilitarla", @@ -3435,6 +3723,8 @@ public void run() { break; case CKR_GENERAL_ERROR: + logger.Error( + "Errore inaspettato durante la comunicazione con la smart card"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "Errore inaspettato durante la comunicazione con la smart card", @@ -3444,6 +3734,7 @@ public void run() { break; case CKR_OK: + logger.Info("CIE abilitata con successo"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "L'abilitazione della CIE è avvennuta con successo", @@ -3461,6 +3752,8 @@ public void run() { selectCardholder(); break; case CARD_ALREADY_ENABLED: + logger.Error( + "Carta già abilitata, abbinamento impossibile"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "Carta già abilitata", @@ -3483,6 +3776,7 @@ public void run() { } private void cambiaPIN() { + logger.Info("Inizia - cambiaPIN()"); final String pin = oldpin.getText(); final String pin1 = newpin1.getText(); final String pin2 = newpin2.getText(); @@ -3490,6 +3784,7 @@ private void cambiaPIN() { int i; if (pin.length() != 8) { + logger.Error("PIN non corretto"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "Il PIN deve essere composto da 8 numeri", @@ -3499,6 +3794,7 @@ private void cambiaPIN() { } if (pin1.length() != 8) { + logger.Error("PIN non corretto"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "Il PIN deve essere composto da 8 numeri", @@ -3515,6 +3811,7 @@ private void cambiaPIN() { } if (i < pin.length() || !(c >= '0' && c <= '9')) { + logger.Error("PIN non corretto"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "Il PIN deve essere composto da 8 numeri", @@ -3531,6 +3828,7 @@ private void cambiaPIN() { } if (i < pin1.length() || !(c >= '0' && c <= '9')) { + logger.Error("PIN non corretto"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "Il PIN deve essere composto da 8 numeri", @@ -3540,6 +3838,7 @@ private void cambiaPIN() { } if (!pin1.equals(pin2)) { + logger.Error("PIN non corrispondenti"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "I PIN non corrispondono", @@ -3557,6 +3856,7 @@ private void cambiaPIN() { } if (c == lastchar) { + logger.Error("PIN non valido - cifre tutte uguali"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "Il nuovo PIN non deve essere composto da cifre uguali", @@ -3574,6 +3874,7 @@ private void cambiaPIN() { } if (c == lastchar + 1) { + logger.Error("PIN non corretto - cifre consecutive"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "Il nuovo PIN non deve essere composto da cifre consecutive", @@ -3591,6 +3892,7 @@ private void cambiaPIN() { } if (c == lastchar - 1) { + logger.Error("PIN non corretto - cifre consecutive"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "Il nuovo PIN non deve essere composto da cifre consecutive", @@ -3644,6 +3946,7 @@ public void run() { switch (ret) { case CKR_TOKEN_NOT_RECOGNIZED: + logger.Error("CIE non presente sul lettore"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "CIE non presente sul lettore", @@ -3653,6 +3956,7 @@ public void run() { break; case CKR_TOKEN_NOT_PRESENT: + logger.Error("CIE non presente sul lettore"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "CIE non presente sul lettore", @@ -3662,6 +3966,10 @@ public void run() { break; case CKR_PIN_INCORRECT: + logger.Error( + String.format( + "Il PIN digitato è errato. rimangono %d tentativi", + attempts[0])); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), String.format( @@ -3673,6 +3981,7 @@ public void run() { break; case CKR_PIN_LOCKED: + logger.Error("Carta bloccata"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "Munisciti del codice PUK e utilizza la funzione di sblocco carta per abilitarla", @@ -3682,6 +3991,8 @@ public void run() { break; case CKR_GENERAL_ERROR: + logger.Error( + "Errore inaspettato durante la comunicazione con la smart card"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "Errore inaspettato durante la comunicazione con la smart card", @@ -3691,6 +4002,8 @@ public void run() { break; case CKR_OK: + logger.Info( + "Il PIN è stato modificato con successo"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "Il PIN è stato modificato con successo", @@ -3709,6 +4022,7 @@ public void run() { } private void sbloccaPIN() { + logger.Info("Inizia - sbloccaPIN()"); final String puk = puk01.getText(); final String pin1 = pin01.getText(); final String pin2 = pin02.getText(); @@ -3716,6 +4030,7 @@ private void sbloccaPIN() { int i; if (puk.length() != 8) { + logger.Error("PUK non corretto - deve essere composto da 8 numeri"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "Il PUK deve essere composto da 8 numeri", @@ -3725,6 +4040,7 @@ private void sbloccaPIN() { } if (pin1.length() != 8) { + logger.Error("PIN non corretto - deve essere composto da 8 numeri"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "Il PIN deve essere composto da 8 numeri", @@ -3741,6 +4057,7 @@ private void sbloccaPIN() { } if (i < puk.length() || !(c >= '0' && c <= '9')) { + logger.Error("PUK non corretto - deve essere composto da 8 numeri"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "Il PUK deve essere composto da 8 numeri", @@ -3757,6 +4074,7 @@ private void sbloccaPIN() { } if (i < pin1.length() || !(c >= '0' && c <= '9')) { + logger.Error("PIN non corretto - deve essere composto da 8 numeri"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "Il PIN deve essere composto da 8 numeri", @@ -3766,6 +4084,7 @@ private void sbloccaPIN() { } if (!pin1.equals(pin2)) { + logger.Error("PIN non corrispondenti"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "I PIN non corrispondono", @@ -3783,6 +4102,7 @@ private void sbloccaPIN() { } if (c == lastchar) { + logger.Error("PIN non valido - cifre tutte uguali"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "Il nuovo PIN non deve essere composto da cifre uguali", @@ -3800,6 +4120,7 @@ private void sbloccaPIN() { } if (c == lastchar + 1) { + logger.Error("PIN non valido - cifre consecutive"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "Il nuovo PIN non deve essere composto da cifre consecutive", @@ -3817,6 +4138,7 @@ private void sbloccaPIN() { } if (c == lastchar - 1) { + logger.Error("PIN non valido - cifre consecutive"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "Il nuovo PIN non deve essere composto da cifre consecutive", @@ -3870,6 +4192,7 @@ public void run() { switch (ret) { case CKR_TOKEN_NOT_RECOGNIZED: + logger.Error("CIE non presente sul lettore"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "CIE non presente sul lettore", @@ -3879,6 +4202,7 @@ public void run() { break; case CKR_TOKEN_NOT_PRESENT: + logger.Error("CIE non presente sul lettore"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "CIE non presente sul lettore", @@ -3888,6 +4212,10 @@ public void run() { break; case CKR_PIN_INCORRECT: + logger.Error( + String.format( + "Il PUK digitato è errato. rimangono %d tentativi", + attempts[0])); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), String.format( @@ -3899,15 +4227,19 @@ public void run() { break; case CKR_PIN_LOCKED: + logger.Error( + "PUK bloccato - la CIE deve essere sostituita"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), - "PUK bloccato. La tua CIE deve essere sostutuita", + "PUK bloccato. La tua CIE deve essere sostituita", "Carta bloccata", JOptionPane.ERROR_MESSAGE); tabbedPane.setSelectedIndex(5); break; case CKR_GENERAL_ERROR: + logger.Error( + "Errore inaspettato durante la comunicazione con la smart card"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "Errore inaspettato durante la comunicazione con la smart card", @@ -3917,6 +4249,7 @@ public void run() { break; case CKR_OK: + logger.Info("CIE sbloccata con successo"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "La CIE è stata sbloccata con successo", @@ -3935,6 +4268,7 @@ public void run() { } private void disabilitaCIE(String pan, String name) { + logger.Info("Inizia - disabilitaCIE()"); if (JOptionPane.showConfirmDialog( this.getContentPane(), @@ -3950,6 +4284,7 @@ private void disabilitaCIE(String pan, String name) { switch (ret) { case CKR_OK: + logger.Info("CIE disabilitata con successo"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "CIE disabilitata con successo", @@ -3960,14 +4295,21 @@ private void disabilitaCIE(String pan, String name) { String signPath = getSignImagePath(cie.getSerialNumber()); try { + logger.Info(String.format("Cancello '%s'", signPath)); Files.deleteIfExists(Paths.get(signPath)); } catch (NoSuchFileException x) { - System.err.format("%s: no such" + " file or directory%n", signPath); + String msg = String.format("%s: no such file or directory", signPath); + logger.Error(msg); + System.err.println(msg); } catch (DirectoryNotEmptyException x) { - System.err.format("%s not empty%n", signPath); + String msg = String.format("%s not empty", signPath); + logger.Error(msg); + System.err.println(msg); } catch (IOException x) { // File permission problems are caught here. - System.err.println(x); + String msg = x.toString(); + logger.Error(msg); + System.err.println(msg); } cieDictionary.remove(pan); @@ -3979,6 +4321,7 @@ private void disabilitaCIE(String pan, String name) { selectHome(); break; default: + logger.Error("Impossibile disabilitare la CIE"); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "Impossibile disabilitare la CIE di " + name, @@ -3989,6 +4332,7 @@ private void disabilitaCIE(String pan, String name) { } private void disabilitaAllCIE(List cieList) { + logger.Info("Inizia - disabilitaAllCIE()"); if (JOptionPane.showConfirmDialog( this.getContentPane(), @@ -4007,14 +4351,21 @@ private void disabilitaAllCIE(List cieList) { String signPath = getSignImagePath(cieList.get(i).getSerialNumber()); try { + logger.Info(String.format("Cancello '%s'", signPath)); Files.deleteIfExists(Paths.get(signPath)); } catch (NoSuchFileException x) { - System.err.format("%s: no such" + " file or directory%n", signPath); + String msg = String.format("%s: no such" + " file or directory", signPath); + logger.Error(msg); + System.err.println(msg); } catch (DirectoryNotEmptyException x) { - System.err.format("%s not empty%n", signPath); + String msg = String.format("%s not empty", signPath); + logger.Error(msg); + System.err.println(msg); } catch (IOException x) { // File permission problems are caught here. - System.err.println(x); + String msg = x.toString(); + logger.Error(msg); + System.err.println(msg); } Gson gson = new Gson(); @@ -4023,6 +4374,8 @@ private void disabilitaAllCIE(List cieList) { break; default: + logger.Error( + "Impossibile disabilitare la CIE " + cieList.get(i).getSerialNumber()); JOptionPane.showMessageDialog( MainFrame.this.getContentPane(), "Impossibile disabilitare la CIE numero " @@ -4043,6 +4396,7 @@ private void disabilitaAllCIE(List cieList) { } private void configureHomeButtons(Map cieDictionary) { + logger.Info("Inizia - configureHomeButtons()"); btnSelezionaCIE.setVisible(false); btnNewButton.setVisible(true); btnRemoveSelected.setVisible(true); @@ -4059,6 +4413,7 @@ private void configureHomeButtons(Map cieDictionary) { } private void selectHome() { + logger.Info("Inizia - selectHome()"); /* if(Utils.getProperty("ef_seriale", "").equals("") && !Utils.getProperty("cardholder", "").equals("") ) { @@ -4087,12 +4442,12 @@ else if(!Utils.getProperty("ef_seriale", "").equals("")) { tabbedPane.setSelectedIndex(0); EventQueue.invokeLater(new Runnable() - { + { public void run() { passwordField.requestFocus(); } - }); + }); }*/ // Utils.setProperty("cieDictionary", ""); @@ -4190,6 +4545,7 @@ private String toFirstCharUpperAll(String string) { } private void selectCardholder() { + logger.Info("Inizia - selectCardholder()"); // tabbedPane.setSelectedIndex(2); selectHome(); configureHomeButtons(cieDictionary); @@ -4197,7 +4553,84 @@ private void selectCardholder() { } private void selectUnlock() { + logger.Info("Inizia - selectUnlock()"); tabbedPane.setSelectedIndex(5); selectButton(btnSbloccaCarta); } + + /** Logger */ + public void LoadLogConfigFromFile() { + boolean writeLogConfigFile = false; + Path configFilePath = Paths.get(System.getProperty("user.home"), ".CIEPKI", "config"); + try { + List configFileLines = Files.readAllLines(configFilePath); + for (String line : configFileLines) { + boolean isAppConfigLine = line.contains(LOG_CONFIG_PREFIX_APP); + boolean isLibConfigLine = line.contains(LOG_CONFIG_PREFIX_LIB); + if ((isAppConfigLine || isLibConfigLine) && (isAppConfigLine != isLibConfigLine)) { + String value = line.split("=")[1]; + try { + Integer intValue = new Integer(value); + try { + LogLevel valueLevel = LogLevel.getLevelFromInteger(intValue); + if (valueLevel.compareTo(LogLevel.NONE) >= 0 + && valueLevel.compareTo(LogLevel.ERROR) <= 0) { + if (isAppConfigLine) { + logConfig.app = valueLevel; + } else { + logConfig.lib = valueLevel; + } + } + } catch (IllegalArgumentException exception) { + if (isAppConfigLine) { + System.out.println( + String.format( + "valore '%s' del livello di log applicazione fuori intervallo - uso default", + intValue)); + + } else { + System.out.println( + String.format( + "valore '%s' del livello di log libreria fuori intervallo - uso default", + intValue)); + } + writeLogConfigFile = true; + } + } catch (Exception exception) { + System.out.println( + String.format( + "valore '%s' del livello di log libreria non valido - uso default", + value)); + writeLogConfigFile = true; + } + } else { + System.out.println( + String.format("Riga di configurazione log non valida: %s", line)); + } + } + } catch (Exception exception) { + System.out.println( + "File configurazione log non trovato, lo creo con valori di default"); + writeLogConfigFile = true; + } + + if (writeLogConfigFile) { + SaveLogConfigToFile(); + } + logger.setLevel(logConfig.app); + } + + private void SaveLogConfigToFile() { + logger.Info("Inizia - SaveLogConfigToFile()"); + Path configFilePath = Paths.get(System.getProperty("user.home"), ".CIEPKI", "config"); + List configList = new ArrayList(); + configList.add(String.format("%s=%s", LOG_CONFIG_PREFIX_LIB, logConfig.lib.ordinal())); + configList.add(String.format("%s=%s", LOG_CONFIG_PREFIX_APP, logConfig.app.ordinal())); + try { + Files.write(configFilePath, configList); + } catch (Exception exception) { + System.out.println("Impossibile salvare il file di configurazione"); + System.out.println(exception); + } + } } diff --git a/cie-java/src/main/it/ipzs/cieid/Middleware.java b/cie-java/src/main/it/ipzs/cieid/Middleware.java index 98d160df..a78c4e2f 100644 --- a/cie-java/src/main/it/ipzs/cieid/Middleware.java +++ b/cie-java/src/main/it/ipzs/cieid/Middleware.java @@ -120,11 +120,9 @@ int firmaConCIE( int CambioPIN( String currentPIN, String nuovoPIN, int[] attempts, ProgressCallBack progressCallBack); - int SbloccoPIN( - String puk, String nuovoPIN, int[] attempts, ProgressCallBack progressCallBack); + int SbloccoPIN(String puk, String nuovoPIN, int[] attempts, ProgressCallBack progressCallBack); - int verificaConCIE( - String inFilePath, String proxyAddress, int proxyPort, String usrPass); + int verificaConCIE(String inFilePath, String proxyAddress, int proxyPort, String usrPass); int getNumberOfSign(); diff --git a/libcie-pkcs11/CSP/AbilitaCIE.cpp b/libcie-pkcs11/CSP/AbilitaCIE.cpp index 48bd730f..58f49169 100644 --- a/libcie-pkcs11/CSP/AbilitaCIE.cpp +++ b/libcie-pkcs11/CSP/AbilitaCIE.cpp @@ -42,6 +42,10 @@ #include #include +#include "../LOGGER/Logger.h" + +using namespace CieIDLogger; + #define ROLE_USER 1 #define ROLE_ADMIN 2 #define CARD_ALREADY_ENABLED 0x000000F0; @@ -93,7 +97,11 @@ CK_RV CK_ENTRY VerificaCIEAbilitata(const char* szPAN) { CK_RV CK_ENTRY DisabilitaCIE(const char* szPAN) { if(IAS::IsEnrolled(szPAN)) { IAS::Unenroll(szPAN); + LOG_INFO("DisabilitaCIE - CIE number %s removed", szPAN); return CKR_OK; + } else { + LOG_ERROR("DisabilitaCIE - Unable to remove CIE number %s, CIE is not enrolled", szPAN); + return CKR_FUNCTION_FAILED; } return CKR_FUNCTION_FAILED; @@ -103,6 +111,9 @@ CK_RV CK_ENTRY AbilitaCIE(const char* szPAN, const char* szPIN, int* attempts, char* readers = NULL; char* ATR = NULL; + LOG_INFO("***** Starting AbbinaCIE *****"); + LOG_DEBUG("szPAN:%s, pin len : %d", szPAN, strlen(szPIN)); + // verifica bontà PIN if(szPIN == NULL || strnlen(szPIN, 9) != 8) { return CKR_PIN_LEN_RANGE; @@ -125,24 +136,35 @@ CK_RV CK_ENTRY AbilitaCIE(const char* szPAN, const char* szPIN, int* attempts, SCARDCONTEXT hSC; + LOG_INFO("AbbinaCIE - Connecting to CIE..."); progressCallBack(1, "Connessione alla CIE"); long nRet = SCardEstablishContext(SCARD_SCOPE_USER, nullptr, nullptr, &hSC); - if(nRet != SCARD_S_SUCCESS) + if(nRet != SCARD_S_SUCCESS) { + LOG_ERROR("AbbinaCIE - SCardEstablishContext error: %d", nRet); return CKR_DEVICE_ERROR; + } - if (SCardListReaders(hSC, nullptr, NULL, &len) != SCARD_S_SUCCESS) { + nRet = SCardListReaders(hSC, nullptr, NULL, &len); + if (nRet != SCARD_S_SUCCESS) { + LOG_ERROR("AbbinaCIE - SCardListReaders error: %d. Len: %d", nRet, len); return CKR_TOKEN_NOT_PRESENT; } + if(len == 1) + return CKR_TOKEN_NOT_PRESENT; + readers = (char*)malloc(len); - if (SCardListReaders(hSC, nullptr, (char*)readers, &len) != SCARD_S_SUCCESS) { + nRet = SCardListReaders(hSC, nullptr, (char*)readers, &len); + if (nRet != SCARD_S_SUCCESS) { + LOG_ERROR("AbbinaCIE - SCardListReaders error: %d", nRet); free(readers); return CKR_TOKEN_NOT_PRESENT; } progressCallBack(5, "CIE Connessa"); + LOG_INFO("AbbinaCIE - CIE Connected"); char *curreader = readers; bool foundCIE = false; @@ -152,14 +174,18 @@ CK_RV CK_ENTRY AbilitaCIE(const char* szPAN, const char* szPIN, int* attempts, continue; DWORD atrLen = 40; - if(SCardGetAttrib(conn.hCard, SCARD_ATTR_ATR_STRING, (uint8_t*)ATR, &atrLen) != SCARD_S_SUCCESS) { + nRet = SCardGetAttrib(conn.hCard, SCARD_ATTR_ATR_STRING, (uint8_t*)ATR, &atrLen); + if(nRet != SCARD_S_SUCCESS) { + LOG_ERROR("AbbinaCIE - SCardGetAttrib error, %d\n", nRet); free(readers); return CKR_DEVICE_ERROR; } ATR = (char*)malloc(atrLen); - if(SCardGetAttrib(conn.hCard, SCARD_ATTR_ATR_STRING, (uint8_t*)ATR, &atrLen) != SCARD_S_SUCCESS) { + nRet = SCardGetAttrib(conn.hCard, SCARD_ATTR_ATR_STRING, (uint8_t*)ATR, &atrLen); + if(nRet != SCARD_S_SUCCESS) { + LOG_ERROR("AbbinaCIE - SCardGetAttrib error, %d\n", nRet); free(readers); free(ATR); return CKR_DEVICE_ERROR; @@ -188,10 +214,13 @@ CK_RV CK_ENTRY AbilitaCIE(const char* szPAN, const char* szPIN, int* attempts, ias.ReadIdServizi(IdServizi); if (ias.IsEnrolled()) { + LOG_ERROR("AbbinaCIE - CIE already enabled. Serial number: %s\n", IdServizi.data()); return CARD_ALREADY_ENABLED; } progressCallBack(15, "Lettura dati dalla CIE"); + LOG_INFO("AbbinaCIE - Reading data from CIE..."); + ByteArray serviziData(IdServizi.left(12)); ByteDynArray SOD; @@ -224,10 +253,19 @@ CK_RV CK_ENTRY AbilitaCIE(const char* szPAN, const char* szPIN, int* attempts, DWORD rs = CardAuthenticateEx(&ias, ROLE_USER, FULL_PIN, (BYTE*)szPIN, (DWORD)strnlen(szPIN, sizeof(szPIN)), nullptr, 0, progressCallBack, attempts); if (rs == SCARD_W_WRONG_CHV) { + LOG_ERROR("AbbinaCIE - CardAuthenticateEx Wrong Pin"); + free(ATR); + free(readers); return CKR_PIN_INCORRECT; } else if (rs == SCARD_W_CHV_BLOCKED) { + LOG_ERROR("AbbinaCIE - CardAuthenticateEx Pin locked"); + free(ATR); + free(readers); return CKR_PIN_LOCKED; } else if (rs != SCARD_S_SUCCESS) { + LOG_ERROR("AbbinaCIE - CardAuthenticateEx Generic error, res:%d", rs); + free(ATR); + free(readers); return CKR_GENERAL_ERROR; } @@ -238,15 +276,15 @@ CK_RV CK_ENTRY AbilitaCIE(const char* szPAN, const char* szPIN, int* attempts, ias.ReadSerialeCIE(Serial); ByteArray serialData = Serial.left(9); std::string st_serial((char*)serialData.data(), serialData.size()); - printf("\nserial data: %s\n", st_serial.c_str()); - progressCallBack(55, "Lettura certificato"); + LOG_INFO("AbbinaCIE - Reading certificate..."); ByteDynArray CertCIE; ias.ReadCertCIE(CertCIE); ByteArray certCIEData = CertCIE.left(GetASN1DataLenght(CertCIE)); + LOG_INFO("AbbinaCIE - Verifying SOD, digest algorithm: %s", (digest == 1) ? "RSA/SHA256" : "RSA-PSS/SHA512"); if (digest == 1) { CSHA256 sha256; hashSet[0xa1] = sha256.Digest(serviziData); @@ -271,6 +309,7 @@ CK_RV CK_ENTRY AbilitaCIE(const char* szPAN, const char* szPIN, int* attempts, ByteArray pinBa((uint8_t*)szPIN, 4); progressCallBack(85, "Memorizzazione in cache"); + LOG_INFO("AbbinaCIE - Saving certificate in cache..."); std::string sidServizi((char*)IdServizi.data(), IdServizi.size()); @@ -331,12 +370,15 @@ CK_RV CK_ENTRY AbilitaCIE(const char* szPAN, const char* szPIN, int* attempts, } if (!foundCIE) { + LOG_ERROR("AbbinaCIE - No CIE available"); + free(ATR); + free(readers); return CKR_TOKEN_NOT_RECOGNIZED; } } catch (std::exception &ex) { - OutputDebugString("%s", ex.what()); + LOG_ERROR("AbbinaCIE - Exception %s ", ex.what()); if(ATR) free(ATR); @@ -350,7 +392,9 @@ CK_RV CK_ENTRY AbilitaCIE(const char* szPAN, const char* szPIN, int* attempts, if(readers) free(readers); + LOG_INFO("AbbinaCIE - CIE paired successfully"); progressCallBack(100, ""); + LOG_INFO("***** AbbinaCIE Ended *****"); return SCARD_S_SUCCESS; } @@ -367,6 +411,11 @@ DWORD CardAuthenticateEx(IAS* ias, PROGRESS_CALLBACK progressCallBack, int* pcAttemptsRemaining) { + LOG_INFO("***** Starting CardAuthenticateEx *****"); + LOG_DEBUG("Pin id: %d, dwFlags: %d, cbPinData: %d, pbSessionPin: %s, pcAttemptsRemaining: %d", PinId, dwFlags, cbPinData, pcbSessionPin, *pcAttemptsRemaining); + + LOG_INFO("CardAuthenticateEx - Selecting IAS and CIE AID"); + progressCallBack(21, "selected CIE applet"); ias->SelectAID_IAS(); ias->SelectAID_CIE(); @@ -375,6 +424,8 @@ DWORD CardAuthenticateEx(IAS* ias, progressCallBack(22, "init DH Param"); // leggo i parametri di dominio DH e della chiave di extauth + LOG_INFO("CardAuthenticateEx - Reading DH parameters"); + ias->InitDHParam(); @@ -383,6 +434,8 @@ DWORD CardAuthenticateEx(IAS* ias, ByteDynArray dappData; ias->ReadDappPubKey(dappData); + LOG_INFO("CardAuthenticateEx - Performing DH Exchange"); + progressCallBack(26, "InitExtAuthKeyParam"); ias->InitExtAuthKeyParam(); @@ -399,50 +452,53 @@ DWORD CardAuthenticateEx(IAS* ias, // verifica PIN StatusWord sw; if (PinId == ROLE_USER) { - + LOG_INFO("CardAuthenticateEx - Verifying PIN"); ByteDynArray PIN; if ((dwFlags & FULL_PIN) != FULL_PIN) ias->GetFirstPIN(PIN); PIN.append(ByteArray(pbPinData, cbPinData)); sw = ias->VerifyPIN(PIN); } else if (PinId == ROLE_ADMIN) { + LOG_INFO("CardAuthenticateEx - Verifying PUK"); ByteArray pinBa(pbPinData, cbPinData); sw = ias->VerifyPUK(pinBa); - } else + } else { + LOG_ERROR("CardAuthenticateEx - Invalid parameter: wrong PinId value"); return SCARD_E_INVALID_PARAMETER; + } progressCallBack(34, "verifyPIN ok"); if (sw == 0x6983) { - if (PinId == ROLE_USER) { - progressCallBack(40, "PIN Bloccato"); - ias->IconaSbloccoPIN(); - } - + LOG_ERROR("CardAuthenticateEx - Pin locked"); return SCARD_W_CHV_BLOCKED; - } else if (sw >= 0x63C0 && sw <= 0x63CF) { - progressCallBack(40, "PIN Errato"); - - if (pcAttemptsRemaining!=nullptr) + } + if (sw >= 0x63C0 && sw <= 0x63CF) { + if (pcAttemptsRemaining != nullptr) *pcAttemptsRemaining = sw - 0x63C0; return SCARD_W_WRONG_CHV; - } else if (sw == 0x6700) { - progressCallBack(40, "PIN Errato"); + } + if (sw == 0x6700) { + LOG_ERROR("CardAuthenticateEx - Wrong Pin"); return SCARD_W_WRONG_CHV; - } else if (sw == 0x6300) { - progressCallBack(40, "PIN Errato"); + } + if (sw == 0x6300) { + LOG_ERROR("CardAuthenticateEx - Wrong Pin"); return SCARD_W_WRONG_CHV; - } else if (sw != 0x9000) { - progressCallBack(40, "Errore smart card"); - throw scard_error(sw); + } + if (sw != 0x9000) { + LOG_ERROR("CarduAuthenticateEx - Smart Card error: 0x%04X", sw); } - progressCallBack(38, "VerifyPIN OK"); - + LOG_INFO("***** CardAuthenticateEx Ended *****"); return SCARD_S_SUCCESS; } int TokenTransmitCallback(safeConnection *conn, BYTE *apdu, DWORD apduSize, BYTE *resp, DWORD *respSize) { + + LOG_DEBUG("TokenTransmitCallback - Apdu:"); + LOG_BUFFER(apdu, apduSize); + if (apduSize == 2) { WORD code = *(WORD*)apdu; if (code == 0xfffd) { @@ -455,7 +511,7 @@ int TokenTransmitCallback(safeConnection *conn, BYTE *apdu, DWORD apduSize, BYTE return SCARD_S_SUCCESS; } else if (code == 0xfffe) { DWORD protocol = 0; - ODS("%s", "UNPOWER CARD"); + LOG_INFO("TokenTransmitCallback - Unpowering Card"); auto ris = SCardReconnect(conn->hCard, SCARD_SHARE_SHARED, SCARD_PROTOCOL_Tx, SCARD_UNPOWER_CARD, &protocol); @@ -475,28 +531,37 @@ int TokenTransmitCallback(safeConnection *conn, BYTE *apdu, DWORD apduSize, BYTE resp[0] = 0x90; resp[1] = 0x00; } - ODS("%s", "RESET CARD"); + LOG_INFO("TokenTransmitCallback - Resetting Card"); + return ris; } } - //ODS("%s", String().printf("APDU: %s\n", dumpHexData(ByteArray(apdu, apduSize), String()).lock()).lock()); + //ODS(String().printf("APDU: %s\n", dumpHexData(ByteArray(apdu, apduSize), String()).lock()).lock()); auto ris = SCardTransmit(conn->hCard, SCARD_PCI_T1, apdu, apduSize, NULL, resp, respSize); + + LOG_DEBUG("TokenTransmitCallback - Smart card response:"); + LOG_BUFFER(resp, *respSize); + if(ris == SCARD_W_RESET_CARD || ris == SCARD_W_UNPOWERED_CARD) { - ODS("%s", "card resetted"); + LOG_INFO("TokenTransmitCallback - Card Reset done"); + DWORD protocol = 0; ris = SCardReconnect(conn->hCard, SCARD_SHARE_SHARED, SCARD_PROTOCOL_Tx, SCARD_LEAVE_CARD, &protocol); if (ris != SCARD_S_SUCCESS) - ODS("%s", "Errore reconnect"); - else + LOG_ERROR("TokenTransmitCallback - ScardReconnect error: %d"); + else { ris = SCardTransmit(conn->hCard, SCARD_PCI_T1, apdu, apduSize, NULL, resp, respSize); + LOG_DEBUG("TokenTransmitCallback - Smart card response:"); + LOG_BUFFER(resp, *respSize); + } } if (ris != SCARD_S_SUCCESS) { - ODS("%s", "Errore trasmissione APDU"); + LOG_ERROR("TokenTransmitCallback - SCardTransmit error: %d", ris); } //else - //ODS("%s", String().printf("RESP: %s\n", dumpHexData(ByteArray(resp, *respSize), String()).lock()).lock()); + //ODS(String().printf("RESP: %s\n", dumpHexData(ByteArray(resp, *respSize), String()).lock()).lock()); return ris; } @@ -577,70 +642,6 @@ int sendMessage(const char* szCommand, const char* szParam) { return 0; } -//int sendMessageOld(const char* szCommand, const char* szParam) -//{ -// int sock; -// struct sockaddr_in server; -// char szMessage[100] , szServerReply[1000]; -// -// //Create socket -// sock = socket(AF_INET , SOCK_STREAM , 0); -// if (sock == -1) -// { -// printf("Could not create socket"); -// } -// puts("Socket created"); -// -// server.sin_addr.s_addr = inet_addr("127.0.0.1"); -// server.sin_family = AF_INET; -// server.sin_port = htons( 8888 ); -// -// //Connect to remote server -// if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0) -// { -// perror("connect failed. Error"); -// return 1; -// } -// -// puts("Connected\n"); -// -// if(szParam) -// sprintf(szMessage, "%s:%s", szCommand, szParam); -// else -// sprintf(szMessage, "%s", szCommand); -// -// std::string sMessage = szMessage; -// std::string sCipherText; -// -// encrypt(sMessage, sCipherText); -// -// int messagelen = (int)sCipherText.size(); -// std::string sHeader((char*)&messagelen, sizeof(messagelen)); -// -// sMessage = sHeader.append(sCipherText); -// -// //Send some data -// if( send(sock , sMessage.c_str(), (size_t)sMessage.length() , 0) < 0) -// { -// puts("Send failed"); -// return 2; -// } -// -// //Receive a reply from the server -// if( recv(sock , szServerReply , 100 , 0) < 0) -// { -// puts("recv failed"); -// return 3; -// } -// -// puts("Server reply :"); -// puts(szServerReply); -// -// close(sock); -// -// return 0; -//} - void notifyPINLocked() { sendMessage("pinlocked", NULL); } diff --git a/libcie-pkcs11/CSP/ExtAuthKey.cpp b/libcie-pkcs11/CSP/ExtAuthKey.cpp index ee1abdfc..87abbc55 100644 --- a/libcie-pkcs11/CSP/ExtAuthKey.cpp +++ b/libcie-pkcs11/CSP/ExtAuthKey.cpp @@ -1,23 +1,23 @@ -#include "../PKCS11/wintypes.h" -#include "../Util/Array.h" - -BYTE ExtAuth_PrivExp[] = { - 0x18, 0x6B, 0x31, 0x48, 0x8C, 0x25, 0xDC, 0xF8, 0x5D, 0x95, 0x3D, 0x36, 0x30, 0xC0, 0xD0, 0x73, - 0xBA, 0x1C, 0x6A, 0xA2, 0x45, 0x81, 0xAD, 0x25, 0x4F, 0x3B, 0x67, 0x19, 0xC5, 0xD7, 0x2C, 0xCA, - 0x3E, 0x5C, 0xDC, 0x5A, 0x1E, 0x53, 0x16, 0x57, 0x8D, 0x75, 0x95, 0x4F, 0xF7, 0x3B, 0x23, 0x7B, - 0x53, 0x2C, 0x9F, 0x8D, 0xE4, 0xA2, 0xC4, 0xC9, 0x11, 0x38, 0x5A, 0x23, 0xE6, 0x3E, 0x33, 0xE4, - 0x7E, 0xE4, 0x5E, 0x66, 0xEF, 0xD4, 0x9B, 0x18, 0xE0, 0x2C, 0xFF, 0x87, 0x59, 0x8C, 0x39, 0x10, - 0x9E, 0x8F, 0x86, 0xA6, 0x6B, 0xC3, 0x30, 0x24, 0x9C, 0xE3, 0xFC, 0xAD, 0x65, 0x5D, 0xCD, 0xBF, - 0x98, 0xC9, 0xC5, 0xE4, 0x79, 0x32, 0x1A, 0xF5, 0x3B, 0x51, 0x7D, 0x04, 0x10, 0x61, 0x88, 0x0A, - 0x64, 0x7B, 0xBE, 0x0F, 0xF8, 0x13, 0x68, 0x34, 0x70, 0xE6, 0xC5, 0x00, 0x94, 0xCE, 0x81, 0xD0, - 0x64, 0xE2, 0x04, 0xE3, 0x51, 0xBD, 0x3A, 0xE0, 0xA7, 0x94, 0x7D, 0x8E, 0x91, 0xC3, 0xFD, 0x5C, - 0x0A, 0x15, 0x23, 0x3C, 0x34, 0x9A, 0x52, 0x15, 0xA4, 0xE6, 0x6E, 0x21, 0xC5, 0xD3, 0x34, 0x98, - 0xE7, 0x19, 0x91, 0xEA, 0x24, 0x47, 0x3B, 0x29, 0xF1, 0x47, 0x5F, 0x6F, 0xD9, 0xBE, 0x39, 0x96, - 0xE1, 0x9B, 0xD4, 0x74, 0xFA, 0xD1, 0xB4, 0x1E, 0xA0, 0xDC, 0xD2, 0xFC, 0x16, 0xC9, 0xBF, 0xFA, - 0x07, 0x1B, 0xFE, 0xC1, 0xB2, 0x24, 0x15, 0x18, 0x48, 0x11, 0xC1, 0x98, 0x5F, 0xBF, 0xE3, 0xE7, - 0xB4, 0xF4, 0x4A, 0x4B, 0x3C, 0x8D, 0xFA, 0xB4, 0xD9, 0x0C, 0xEC, 0xFC, 0x5E, 0x60, 0x8D, 0x67, - 0x3E, 0x67, 0x62, 0xC6, 0x2C, 0xB7, 0x98, 0x34, 0x12, 0x71, 0x14, 0x9B, 0xA6, 0x88, 0x16, 0x2E, - 0xC7, 0xD0, 0xE3, 0x46, 0x8F, 0x65, 0xA9, 0x4A, 0xB4, 0xAD, 0x1A, 0xB6, 0x7E, 0x37, 0xBF, 0xC1 -}; - -ByteArray baExtAuth_PrivExp(ExtAuth_PrivExp, sizeof(ExtAuth_PrivExp)); +#include "../PKCS11/wintypes.h" +#include "../Util/Array.h" + +BYTE ExtAuth_PrivExp[] = { + 0x18, 0x6B, 0x31, 0x48, 0x8C, 0x25, 0xDC, 0xF8, 0x5D, 0x95, 0x3D, 0x36, 0x30, 0xC0, 0xD0, 0x73, + 0xBA, 0x1C, 0x6A, 0xA2, 0x45, 0x81, 0xAD, 0x25, 0x4F, 0x3B, 0x67, 0x19, 0xC5, 0xD7, 0x2C, 0xCA, + 0x3E, 0x5C, 0xDC, 0x5A, 0x1E, 0x53, 0x16, 0x57, 0x8D, 0x75, 0x95, 0x4F, 0xF7, 0x3B, 0x23, 0x7B, + 0x53, 0x2C, 0x9F, 0x8D, 0xE4, 0xA2, 0xC4, 0xC9, 0x11, 0x38, 0x5A, 0x23, 0xE6, 0x3E, 0x33, 0xE4, + 0x7E, 0xE4, 0x5E, 0x66, 0xEF, 0xD4, 0x9B, 0x18, 0xE0, 0x2C, 0xFF, 0x87, 0x59, 0x8C, 0x39, 0x10, + 0x9E, 0x8F, 0x86, 0xA6, 0x6B, 0xC3, 0x30, 0x24, 0x9C, 0xE3, 0xFC, 0xAD, 0x65, 0x5D, 0xCD, 0xBF, + 0x98, 0xC9, 0xC5, 0xE4, 0x79, 0x32, 0x1A, 0xF5, 0x3B, 0x51, 0x7D, 0x04, 0x10, 0x61, 0x88, 0x0A, + 0x64, 0x7B, 0xBE, 0x0F, 0xF8, 0x13, 0x68, 0x34, 0x70, 0xE6, 0xC5, 0x00, 0x94, 0xCE, 0x81, 0xD0, + 0x64, 0xE2, 0x04, 0xE3, 0x51, 0xBD, 0x3A, 0xE0, 0xA7, 0x94, 0x7D, 0x8E, 0x91, 0xC3, 0xFD, 0x5C, + 0x0A, 0x15, 0x23, 0x3C, 0x34, 0x9A, 0x52, 0x15, 0xA4, 0xE6, 0x6E, 0x21, 0xC5, 0xD3, 0x34, 0x98, + 0xE7, 0x19, 0x91, 0xEA, 0x24, 0x47, 0x3B, 0x29, 0xF1, 0x47, 0x5F, 0x6F, 0xD9, 0xBE, 0x39, 0x96, + 0xE1, 0x9B, 0xD4, 0x74, 0xFA, 0xD1, 0xB4, 0x1E, 0xA0, 0xDC, 0xD2, 0xFC, 0x16, 0xC9, 0xBF, 0xFA, + 0x07, 0x1B, 0xFE, 0xC1, 0xB2, 0x24, 0x15, 0x18, 0x48, 0x11, 0xC1, 0x98, 0x5F, 0xBF, 0xE3, 0xE7, + 0xB4, 0xF4, 0x4A, 0x4B, 0x3C, 0x8D, 0xFA, 0xB4, 0xD9, 0x0C, 0xEC, 0xFC, 0x5E, 0x60, 0x8D, 0x67, + 0x3E, 0x67, 0x62, 0xC6, 0x2C, 0xB7, 0x98, 0x34, 0x12, 0x71, 0x14, 0x9B, 0xA6, 0x88, 0x16, 0x2E, + 0xC7, 0xD0, 0xE3, 0x46, 0x8F, 0x65, 0xA9, 0x4A, 0xB4, 0xAD, 0x1A, 0xB6, 0x7E, 0x37, 0xBF, 0xC1 +}; + +ByteArray baExtAuth_PrivExp(ExtAuth_PrivExp, sizeof(ExtAuth_PrivExp)); diff --git a/libcie-pkcs11/CSP/FirmaConCIE.cpp b/libcie-pkcs11/CSP/FirmaConCIE.cpp index 067795d3..02714c8d 100644 --- a/libcie-pkcs11/CSP/FirmaConCIE.cpp +++ b/libcie-pkcs11/CSP/FirmaConCIE.cpp @@ -1,8 +1,6 @@ // // FirmaConCIE.cpp // cie-pkcs11 -// -// Created by Pierluigi De Gregorio on 18/02/21. // Copyright © 2021 IPZS. All rights reserved. // @@ -16,6 +14,9 @@ #include "../Crypto/ASNParser.h" #include "../Sign/CIESign.h" #include "AbilitaCIE.h" +#include "../LOGGER/Logger.h" + +using namespace CieIDLogger; #define CARD_PAN_MISMATCH (int)(0x000000F1) @@ -27,7 +28,8 @@ extern "C" { CK_RV CK_ENTRY firmaConCIE(const char* inFilePath, const char* type, const char* pin, const char* pan, int page, float x, float y, float w, float h, const char* imagePathFile, const char* outFilePath, PROGRESS_CALLBACK progressCallBack, SIGN_COMPLETED_CALLBACK completedCallBack) { - printf("page: %d, x: %f, y: %f, w: %f, h: %f", page, x, y, w, h); + LOG_INFO("****** Starting firmaConCIE ******"); + LOG_DEBUG("firmaConCIE - page: %d, x: %f, y: %f, w: %f, h: %f", page, x, y, w, h); char* readers = NULL; char* ATR = NULL; @@ -41,13 +43,15 @@ CK_RV CK_ENTRY firmaConCIE(const char* inFilePath, const char* type, const char* SCARDCONTEXT hSC; long nRet = SCardEstablishContext(SCARD_SCOPE_USER, nullptr, nullptr, &hSC); - if (nRet != SCARD_S_SUCCESS) + if (nRet != SCARD_S_SUCCESS) { + LOG_ERROR("firmaConCIE - List readers error: %d\n", nRet); return CKR_DEVICE_ERROR; + } + LOG_INFO("firmaConCIE - Establish Context ok\n"); - OutputDebugString("%s", "Establish Context ok\n"); - - if (SCardListReaders(hSC, nullptr, NULL, &len) != SCARD_S_SUCCESS) { - OutputDebugString("%s", "List readers ko\n"); + nRet = SCardListReaders(hSC, nullptr, NULL, &len); + if ( nRet!= SCARD_S_SUCCESS) { + LOG_ERROR("firmaConCIE - List readers error: %d\n", nRet); return CKR_TOKEN_NOT_PRESENT; } @@ -68,20 +72,15 @@ CK_RV CK_ENTRY firmaConCIE(const char* inFilePath, const char* type, const char* if (!conn.hCard) continue; - LONG res = 0; - DWORD atrLen = 40; - res = SCardGetAttrib(conn.hCard, SCARD_ATTR_ATR_STRING, (uint8_t*)ATR, &atrLen); - if (res != SCARD_S_SUCCESS) { + if(SCardGetAttrib(conn.hCard, SCARD_ATTR_ATR_STRING, (uint8_t*)ATR, &atrLen) != SCARD_S_SUCCESS) { free(readers); - OutputDebugString("%s", "GetAttrib ko 1, %d\n", res); return CKR_DEVICE_ERROR; } - ATR = (char*)malloc(atrLen); - if (SCardGetAttrib(conn.hCard, SCARD_ATTR_ATR_STRING, (uint8_t*)ATR, &atrLen) != SCARD_S_SUCCESS) { + if(SCardGetAttrib(conn.hCard, SCARD_ATTR_ATR_STRING, (uint8_t*)ATR, &atrLen) != SCARD_S_SUCCESS) { free(readers); free(ATR); return CKR_DEVICE_ERROR; @@ -138,7 +137,7 @@ CK_RV CK_ENTRY firmaConCIE(const char* inFilePath, const char* type, const char* progressCallBack(100, ""); - OutputDebugString("%s", "CieSign ret: %d", ret); + LOG_INFO("firmaConCIE - completed, res: %d", ret); free(ias); free(cieSign); @@ -153,14 +152,14 @@ CK_RV CK_ENTRY firmaConCIE(const char* inFilePath, const char* type, const char* } } catch (std::exception &ex) { - OutputDebugString("%s", ex.what()); + LOG_ERROR(ex.what()); if (ATR) free(ATR); - OutputDebugString("%s", "Eccezione: %s", ex.what()); + LOG_ERROR("firmaConCIE - Eccezione: %s", ex.what()); if (readers) free(readers); - OutputDebugString("%s", "General error\n"); + LOG_ERROR("firmaConCIE - General error\n"); return CKR_GENERAL_ERROR; } diff --git a/libcie-pkcs11/CSP/IAS.cpp b/libcie-pkcs11/CSP/IAS.cpp index 84c06da6..05cc032d 100644 --- a/libcie-pkcs11/CSP/IAS.cpp +++ b/libcie-pkcs11/CSP/IAS.cpp @@ -1,1634 +1,1586 @@ -#include "IAS.h" -#include "../Crypto/ASNParser.h" -#include "../Crypto/RSA.h" -#include "../Crypto/AES.h" -#include "../Crypto/sha256.h" -#include "../Crypto/sha512.h" -#include "../Crypto/SHA1.h" -#include "../Crypto/DES3.h" -#include "../Crypto/MAC.h" -#include -#include "../Util/ModuleInfo.h" -#include -#include -#include -#include - -//#include "../res/resource.h" -#include "../Util/CacheLib.h" -//#include - -#define CIE_KEY_DH_ID 0x81 -#define CIE_KEY_ExtAuth_ID 0x84 -#define CIE_PIN_ID 0x81 -#define CIE_PUK_ID 0x82 -#define CIE_KEY_Sign_ID 0x81 - -#include -#include - -extern CLog Log; - -extern CModuleInfo moduleInfo; -extern ByteArray SkipZero(ByteArray &ba); -//extern DWORD WINAPI _abilitaCIE(LPVOID lpThreadParameter); - -void GetPublicKeyFromCert(CryptoPP::BufferedTransformation & certin, - CryptoPP::BufferedTransformation & keyout, - CryptoPP::BufferedTransformation & issuer, - CryptoPP::Integer &serial); - -void showUI(const char* szPAN); -void notifyCardNotRegistered(const char* szPAN); - -IAS::IAS(CToken::TokenTransmitCallback transmit,ByteArray ATR) { - init_func - - Callback = nullptr; - CallbackData = nullptr; - - this->ATR = ATR; - uint8_t gemaltoAID[] = { 0xA0, 0x00, 0x00, 0x00, 0x30, 0x80, 0x00, 0x00, 0x00, 0x09, 0x81, 0x60, 0x01 }; - IAS_AID = VarToByteArray(gemaltoAID); - - uint8_t AID[] = { 0xA0, 0x00, 0x00, 0x00, 0x00, 0x39 }; - CIE_AID = VarToByteArray(AID); - - ActiveSM = false; - ActiveDF = DF_Root; - - token.setTransmitCallback(transmit, nullptr); -} - - -IAS::~IAS() { -} - -uint8_t defModule[] = { 0xba, 0x28, 0x37, 0xab, 0x4c, 0x6b, 0xb8, 0x27, 0x57, 0x7b, 0xff, 0x4e, 0xb7, 0xb1, 0xe4, 0x9c, 0xdd, 0xe0, 0xf1, 0x66, 0x14, 0xd1, 0xef, 0x24, 0xc1, 0xb7, 0x5c, 0xf7, 0x0f, 0xb1, 0x2c, 0xd1, 0x8f, 0x4d, 0x14, 0xe2, 0x81, 0x4b, 0xa4, 0x87, 0x7e, 0xa8, 0x00, 0xe1, 0x75, 0x90, 0x60, 0x76, 0xb5, 0x62, 0xba, 0x53, 0x59, 0x73, 0xc5, 0xd8, 0xb3, 0x78, 0x05, 0x1d, 0x8a, 0xfc, 0x74, 0x07, 0xa1, 0xd9, 0x19, 0x52, 0x9e, 0x03, 0xc1, 0x06, 0xcd, 0xa1, 0x8d, 0x69, 0x9a, 0xfb, 0x0d, 0x8a, 0xb4, 0xfd, 0xdd, 0x9d, 0xc7, 0x19, 0x15, 0x9a, 0x50, 0xde, 0x94, 0x68, 0xf0, 0x2a, 0xb1, 0x03, 0xe2, 0x82, 0xa5, 0x0e, 0x71, 0x6e, 0xc2, 0x3c, 0xda, 0x5b, 0xfc, 0x4a, 0x23, 0x2b, 0x09, 0xa4, 0xb2, 0xc7, 0x07, 0x45, 0x93, 0x95, 0x49, 0x09, 0x9b, 0x44, 0x83, 0xcb, 0xae, 0x62, 0xd0, 0x09, 0x96, 0x74, 0xdb, 0xf6, 0xf3, 0x9b, 0x72, 0x23, 0xa9, 0x9d, 0x88, 0xe3, 0x3f, 0x1a, 0x0c, 0xde, 0xde, 0xeb, 0xbd, 0xc3, 0x55, 0x17, 0xab, 0xe9, 0x88, 0x0a, 0xab, 0x24, 0x0e, 0x1e, 0xa1, 0x66, 0x28, 0x3a, 0x27, 0x4a, 0x9a, 0xd9, 0x3b, 0x4b, 0x1d, 0x19, 0xf3, 0x67, 0x9f, 0x3e, 0x8b, 0x5f, 0xf6, 0xa1, 0xe0, 0xed, 0x73, 0x6e, 0x84, 0xd5, 0xab, 0xe0, 0x3c, 0x59, 0xe7, 0x34, 0x6b, 0x42, 0x18, 0x75, 0x5d, 0x75, 0x36, 0x6c, 0xbf, 0x41, 0x36, 0xf0, 0xa2, 0x6c, 0x3d, 0xc7, 0x0a, 0x69, 0xab, 0xaa, 0xf6, 0x6e, 0x13, 0xa1, 0xb2, 0xfa, 0xad, 0x05, 0x2c, 0xa6, 0xec, 0x9c, 0x51, 0xe2, 0xae, 0xd1, 0x4d, 0x16, 0xe0, 0x90, 0x25, 0x4d, 0xc3, 0xf6, 0x4e, 0xa2, 0xbd, 0x8a, 0x83, 0x6b, 0xba, 0x99, 0xde, 0xfa, 0xcb, 0xa3, 0xa6, 0x13, 0xae, 0xed, 0xd9, 0x3a, 0x96, 0x15, 0x27, 0x3d }; -uint8_t defPrivExp[] = { 0x47, 0x16, 0xc2, 0xa3, 0x8c, 0xcc, 0x7a, 0x07, 0xb4, 0x15, 0xeb, 0x1a, 0x61, 0x75, 0xf2, 0xaa, 0xa0, 0xe4, 0x9c, 0xea, 0xf1, 0xba, 0x75, 0xcb, 0xa0, 0x9a, 0x68, 0x4b, 0x04, 0xd8, 0x11, 0x18, 0x79, 0xd3, 0xe2, 0xcc, 0xd8, 0xb9, 0x4d, 0x3c, 0x5c, 0xf6, 0xc5, 0x57, 0x53, 0xf0, 0xed, 0x95, 0x87, 0x91, 0x0b, 0x3c, 0x77, 0x25, 0x8a, 0x01, 0x46, 0x0f, 0xe8, 0x4c, 0x2e, 0xde, 0x57, 0x64, 0xee, 0xbe, 0x9c, 0x37, 0xfb, 0x95, 0xcd, 0x69, 0xce, 0xaf, 0x09, 0xf4, 0xb1, 0x35, 0x7c, 0x27, 0x63, 0x14, 0xab, 0x43, 0xec, 0x5b, 0x3c, 0xef, 0xb0, 0x40, 0x3f, 0x86, 0x8f, 0x68, 0x8e, 0x2e, 0xc0, 0x9a, 0x49, 0x73, 0xe9, 0x87, 0x75, 0x6f, 0x8d, 0xa7, 0xa1, 0x01, 0xa2, 0xca, 0x75, 0xa5, 0x4a, 0x8c, 0x4c, 0xcf, 0x9a, 0x1b, 0x61, 0x47, 0xe4, 0xde, 0x56, 0x42, 0x3a, 0xf7, 0x0b, 0x20, 0x67, 0x17, 0x9c, 0x5e, 0xeb, 0x64, 0x68, 0x67, 0x86, 0x34, 0x78, 0xd7, 0x52, 0xc7, 0xf4, 0x12, 0xdb, 0x27, 0x75, 0x41, 0x57, 0x5a, 0xa0, 0x61, 0x9d, 0x30, 0xbc, 0xcc, 0x8d, 0x87, 0xe6, 0x17, 0x0b, 0x33, 0x43, 0x9a, 0x2c, 0x93, 0xf2, 0xd9, 0x7e, 0x18, 0xc0, 0xa8, 0x23, 0x43, 0xa6, 0x01, 0x2a, 0x5b, 0xb1, 0x82, 0x28, 0x08, 0xf0, 0x1b, 0x5c, 0xfd, 0x85, 0x67, 0x3a, 0xc0, 0x96, 0x4c, 0x5f, 0x3c, 0xfd, 0x2d, 0xaf, 0x81, 0x42, 0x35, 0x97, 0x64, 0xa9, 0xad, 0xb9, 0xe3, 0xf7, 0x6d, 0xb6, 0x13, 0x46, 0x1c, 0x1b, 0xc9, 0x13, 0xdc, 0x9a, 0xc0, 0xab, 0x50, 0xd3, 0x65, 0xf7, 0x7c, 0xb9, 0x31, 0x94, 0xc9, 0x8a, 0xa9, 0x66, 0xd8, 0x9c, 0xdd, 0x55, 0x51, 0x25, 0xa5, 0xe5, 0x9e, 0xcf, 0x4f, 0xa3, 0xf0, 0xc3, 0xfd, 0x61, 0x0c, 0xd3, 0xd0, 0x56, 0x43, 0x93, 0x38, 0xfd, 0x81 }; -uint8_t defPubExp[] = { 0x00, 0x01, 0x00, 0x01 }; - -void IAS::ReadSOD(ByteDynArray &data) { - init_func - readfile(0x1006,data); - exit_func -} -void IAS::ReadDH(ByteDynArray &data) { - init_func - readfile(0xd004, data); - exit_func -} -void IAS::ReadCertCIE(ByteDynArray &data) { - init_func - readfile(0x1003, data); - exit_func -} -void IAS::ReadServiziPubKey(ByteDynArray &data) { - init_func - readfile(0x1005, data); - exit_func -} -void IAS::ReadSerialeCIE(ByteDynArray &data) { - init_func - readfile(0x1002, data); - exit_func -} -void IAS::ReadIdServizi(ByteDynArray &data) { - init_func - readfile(0x1001, data); - exit_func -} - -void IAS::Sign(ByteArray &data, ByteDynArray &signedData) { - init_func - ByteDynArray resp; - uint8_t SetKey[] = { 0x00, 0x22, 0x41, 0xA4 }; - uint8_t val02 = 2; - uint8_t keyId = CIE_KEY_Sign_ID; - StatusWord sw; - ByteArray val02Ba = VarToByteArray(val02); - ByteArray keyIdBa = VarToByteArray(keyId); - if ((sw = SendAPDU_SM(VarToByteArray(SetKey), ASN1Tag(0x80, val02Ba).append(ASN1Tag(0x84, keyIdBa)), resp)) != 0x9000) - throw scard_error(sw); - - uint8_t Sign[] = { 0x00, 0x88, 0x00, 0x00 }; - if ((sw = SendAPDU_SM(VarToByteArray(Sign), data, signedData)) != 0x9000) - throw scard_error(sw); -} - -StatusWord IAS::VerifyPUK(ByteArray &PIN) { - init_func - ByteDynArray resp; - uint8_t verifyPIN[] = { 0x00, 0x20, 0x00, CIE_PUK_ID }; - return SendAPDU_SM(VarToByteArray(verifyPIN), PIN, resp); -} - -StatusWord IAS::VerifyPIN(ByteArray &PIN) { - init_func - ByteDynArray resp; - uint8_t verifyPIN[] = { 0x00, 0x20, 0x00, CIE_PIN_ID }; - return SendAPDU_SM(VarToByteArray(verifyPIN), PIN, resp); - exit_func -} - -StatusWord IAS::UnblockPIN() { - init_func - ByteDynArray resp; - uint8_t UnblockPIN[] = { 0x00, 0x2C, 0x03, CIE_PIN_ID }; - return SendAPDU_SM(VarToByteArray(UnblockPIN), ByteArray(), resp); - exit_func -} - -StatusWord IAS::ChangePIN(ByteArray &oldPIN,ByteArray &newPIN) { - init_func - ByteDynArray resp; - ByteDynArray data=oldPIN; - data.append(newPIN); - uint8_t ChangePIN[] = { 0x00, 0x24, 0x00, CIE_PIN_ID }; - return SendAPDU_SM(VarToByteArray(ChangePIN), data, resp); - exit_func -} - -StatusWord IAS::ChangePIN(ByteArray &newPIN) { - init_func - ByteDynArray resp; - uint8_t ChangePIN[] = { 0x00, 0x2C, 0x02, CIE_PIN_ID }; - return SendAPDU_SM(VarToByteArray(ChangePIN), newPIN, resp); - exit_func -} - -void IAS::readfile(uint16_t id, ByteDynArray &content) { - init_func - - if (ActiveSM) - return readfile_SM(id, content); - - ByteDynArray resp; - uint8_t selectFile[] = { 0x00, 0xa4, 0x02, 0x04 }; - uint8_t fileId[] = { HIBYTE(id), LOBYTE(id) }; - StatusWord sw; - if ((sw = SendAPDU(VarToByteArray(selectFile), VarToByteArray(fileId), resp)) != 0x9000) - throw scard_error(sw); - - - WORD cnt = 0; - uint8_t chunk = 128; - while (true) { - ByteDynArray chn; - uint8_t readFile[] = { 0x00, 0xb0, HIBYTE(cnt), LOBYTE(cnt) }; - sw = SendAPDU(VarToByteArray(readFile), ByteArray(), chn, &chunk); - if ((sw >> 8) == 0x6c) { - uint8_t le = sw & 0xff; - sw = SendAPDU(VarToByteArray(readFile), ByteArray(), chn, &le); - } - if (sw == 0x9000) { - content.append(chn); - cnt = content.size(); -// WORD chnSize; -// if (FAILED(SizeTToWord(chn.size(), &chnSize)) || FAILED(WordAdd(cnt, chnSize, &cnt))) -// throw logged_error("File troppo grande"); - chunk = 128; - } else { - if (sw == 0x6282) - content.append(chn); - else if (sw != 0x6b00) - throw scard_error(sw); - break; - } - } - exit_func -} - -void IAS::readfile_SM(uint16_t id, ByteDynArray &content) { - init_func - - ByteDynArray resp; - uint8_t selectFile[] = { 0x00, 0xa4, 0x02, 0x04 }; - uint8_t fileId[] = { HIBYTE(id), LOBYTE(id) }; - StatusWord sw; - if ((sw = SendAPDU_SM(VarToByteArray(selectFile), VarToByteArray(fileId), resp)) != 0x9000) - throw scard_error(sw); - - - WORD cnt = 0; - uint8_t chunk = 128; - while (true) { - ByteDynArray chn; - uint8_t readFile[] = { 0x00, 0xb0, HIBYTE(cnt), LOBYTE(cnt) }; - sw = SendAPDU_SM(VarToByteArray(readFile), ByteArray(), chn, &chunk); - if ((sw >> 8) == 0x6c) { - uint8_t le = sw & 0xff; - sw = SendAPDU_SM(VarToByteArray(readFile), ByteArray(), chn, &le); - } - if (sw == 0x9000) { - content.append(chn); - cnt = content.size(); -// WORD chnSize; -// if (FAILED(SizeTToWord(chn.size(), &chnSize)) || FAILED(WordAdd(cnt, chnSize, &cnt))) -// throw logged_error("File troppo grande"); - chunk = 128; - } else { - if (sw == 0x6282) - content.append(chn); - else if (sw != 0x6b00) - throw scard_error(sw); - break; - } - } - exit_func -} - -void IAS::SelectAID_CIE(bool SM) { - init_func - ByteDynArray resp; - uint8_t selectCIE[] = { 0x00, 0xa4, 0x04, 0x0c }; - ByteDynArray selectCIEapdu; - StatusWord sw; - if (SM) { - if ((sw = SendAPDU_SM(VarToByteArray(selectCIE), CIE_AID, resp)) != 0x9000) - throw scard_error(sw); - } else { - if ((sw = SendAPDU(VarToByteArray(selectCIE), CIE_AID, resp)) != 0x9000) - throw scard_error(sw); - } - ActiveDF = DF_CIE; - ActiveSM = false; - exit_func -} - -uint8_t NXP_ATR[] = { 0x80, 0x31, 0x80, 0x65, 0x49, 0x54, 0x4E, 0x58, 0x50 }; -uint8_t Gemalto_ATR[] = { 0x80, 0x31, 0x80, 0x65, 0xB0, 0x85, 0x04, 0x00, 0x11 }; -uint8_t Gemalto2_ATR[] = { 0x80, 0x31, 0x80, 0x65, 0xB0, 0x85, 0x03, 0x00, 0xEF }; -uint8_t STM_ATR[] = {0x80, 0x66, 0x47, 0x50, 0x00, 0xB8, 0x00, 0x7F}; -uint8_t STM2_ATR[] = { 0x80, 0x80, 0x01, 0x01 }; -uint8_t STM3_ATR[] = { 0x80, 0x01, 0x80, 0x66, 0x47, 0x50, 0x00, 0xB8, 0x00, 0x94, 0x82, 0x90, 0x00, 0xC5 }; - -ByteArray baNXP_ATR(NXP_ATR, sizeof(NXP_ATR)); -ByteArray baGemalto_ATR(Gemalto_ATR, sizeof(Gemalto_ATR)); -ByteArray baGemalto2_ATR(Gemalto2_ATR, sizeof(Gemalto2_ATR)); -ByteArray baSTM_ATR(STM_ATR, sizeof(STM_ATR)); -ByteArray baSTM2_ATR(STM2_ATR, sizeof(STM2_ATR)); -ByteArray baSTM3_ATR(STM3_ATR, sizeof(STM3_ATR)); - -void IAS::ReadCIEType() { - init_func - size_t position; - if (ATR.indexOf(baNXP_ATR,position)) - type = CIE_Type::CIE_NXP; - else if (ATR.indexOf(baGemalto_ATR, position)) { - printf("%s\n", "CIE Gemalto"); - type = CIE_Type::CIE_Gemalto; - } else if (ATR.indexOf(baGemalto2_ATR, position)) { - printf("%s", "CIE Gemalto"); - type = CIE_Type::CIE_Gemalto; - } else if (ATR.indexOf(baSTM_ATR, position)) - type = CIE_Type::CIE_STM; - else if (ATR.indexOf(baSTM2_ATR, position)) - type = CIE_Type::CIE_STM2; - else if (ATR.indexOf(baSTM3_ATR, position)) - type = CIE_Type::CIE_STM3; - else { - printf("%s", "CIE non riconosciuta"); - throw logged_error("CIE non riconosciuta"); - } -} - - -void IAS::SelectAID_IAS(bool SM) { - init_func - if (type == CIE_Type::CIE_Unknown) { - ReadCIEType(); - } - ByteDynArray resp; - StatusWord sw; - - if (type == CIE_Type::CIE_NXP) { - uint8_t selectMF[] = { 0x00, 0xa4, 0x00, 0x00 }; - - if (SM) { - if ((sw = SendAPDU_SM(VarToByteArray(selectMF), ByteArray(), resp)) != 0x9000) - throw scard_error(sw); - } else { - if ((sw = SendAPDU(VarToByteArray(selectMF), ByteArray(), resp)) != 0x9000) - throw scard_error(sw); - } - } else if (type == CIE_Type::CIE_Gemalto || type == CIE_Type::CIE_STM || type == CIE_Type::CIE_STM2 || type == CIE_Type::CIE_STM3) { - uint8_t selectIAS[] = { 0x00, 0xa4, 0x04, 0x0c }; - if (SM) { - if ((sw = SendAPDU_SM(VarToByteArray(selectIAS), IAS_AID, resp)) != 0x9000) - throw scard_error(sw); - } else { - if ((sw = SendAPDU(VarToByteArray(selectIAS), IAS_AID, resp)) != 0x9000) - throw scard_error(sw); - } - } else { - throw logged_error("Tipo CIE sconosciuto"); - } - - SM = false; - - ActiveDF = DF_IAS; - ActiveSM = false; - exit_func -} - -void IAS::ReadDappPubKey(ByteDynArray &DappKey) { - init_func - ByteDynArray resp; - readfile(0x1004, DappKey); - - CASNParser parser; - parser.Parse(DappKey); - ByteArray module = parser.tags[0]->tags[0]->content; - while (module[0] == 0) - module = module.mid(1); - DappModule = module; - ByteArray pubKey = parser.tags[0]->tags[1]->content; - while (pubKey[0] == 0) - pubKey = pubKey.mid(1); - DappPubKey = pubKey; - exit_func -} - -void IAS::ReadPAN() { - init_func - readfile(0xd003, PAN); - - exit_func -} - -void IAS::DAPP() { - init_func - - ByteDynArray resp; - uint8_t psoVerifyAlgo = 0x41; - uint8_t PKdScheme = 0x9B; - uint8_t shaOID = 0x04; - DWORD shaSize = 32; - CSHA256 sha256; -// uint8_t Val01 = 1; - - if (DappPubKey.isEmpty()) { - throw logged_error("La chiave DAPP non e' diponibile"); - } - - ByteDynArray module = VarToByteArray(defModule); - ByteDynArray pubexp = VarToByteArray(defPubExp); - ByteDynArray privexp = VarToByteArray(defPrivExp); - - ByteDynArray cert; - ByteDynArray CHR, CHA, OID; - - - uint8_t snIFD[] = { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }; - uint8_t CPI=0x8A; - uint8_t baseCHR[] = { 0x00, 0x00, 0x00, 0x00 }; - - ByteArray baseCHRBa = VarToByteArray(baseCHR); - ByteArray snIFDBa = VarToByteArray(snIFD); - - CHR.set(&baseCHRBa, &snIFDBa); - CHA.set(&CA_AID,01); - uint8_t baseOID[] = { 0x2A, 0x81, 0x22, 0xF4, 0x2A, 0x02, 0x04, 0x01 }; - - ByteArray baseOIDBa = VarToByteArray(baseOID); - OID.set(&baseOIDBa, shaOID); - - ByteDynArray endEntityCert; - endEntityCert.set(CPI, &CA_CAR, &CHR, &CHA, &OID, &module, &pubexp); - - ByteDynArray certSign, toSign; -// uint8_t ValBC = 0xBC; - - ByteArray endEntityCertBa = endEntityCert.left(CA_module.size() - shaSize - 2); - - ByteDynArray endEntityCertDigestBa = sha256.Digest(endEntityCert); - - toSign.set(0x6A, &endEntityCertBa, &endEntityCertDigestBa, 0xbc); - CRSA caKey(CA_module, CA_privexp); - - certSign = caKey.RSA_PURE(toSign); - - ByteDynArray certVerif; - CRSA caPubKey(CA_module, CA_pubexp); - - certVerif = caPubKey.RSA_PURE(certSign); - ER_ASSERT(certVerif == toSign, "Errore in verifica firma!") - - ByteDynArray PkRem; - PkRem = endEntityCert.mid(CA_module.size() - shaSize - 2); - - cert.setASN1Tag(0x7F21, ASN1Tag(0x5F37, certSign).append(ASN1Tag(0x5F38, PkRem)).append(ASN1Tag(0x42, CA_CAR))); - - uint8_t SelectKey[] = { 0x00, 0x22, 0x81, 0xb6 }; - uint8_t id = CIE_KEY_ExtAuth_ID; - StatusWord sw; - - uint8_t le = 0; - ByteArray psoVerifyAlgoBa = VarToByteArray(psoVerifyAlgo); - ByteArray idBa = VarToByteArray(id); - if ((sw = SendAPDU_SM(VarToByteArray(SelectKey), ASN1Tag(0x80, psoVerifyAlgoBa).append(ASN1Tag(0x83, idBa)), resp, &le)) != 0x9000) - throw scard_error(sw); - - uint8_t VerifyCert[] = { 0x00, 0x2A, 0x00, 0xAE }; - if ((sw = SendAPDU_SM(VarToByteArray(VerifyCert), cert, resp)) != 0x9000) - throw scard_error(sw); - - uint8_t SetCHR[] = { 0x00, 0x22, 0x81, 0xA4 }; - - if ((sw = SendAPDU_SM(VarToByteArray(SetCHR), ASN1Tag(0x83, CHR), resp)) != 0x9000) - throw scard_error(sw); - - ByteDynArray challenge; - uint8_t GetChallenge[] = { 0x00, 0x84, 0x00, 0x00 }; - uint8_t chLen = 8; - - if ((sw = SendAPDU_SM(VarToByteArray(GetChallenge), ByteArray(), challenge, &chLen)) != 0x9000) - throw scard_error(sw); - - ByteDynArray toHash; - size_t padSize = module.size() - shaSize - 2; - ByteDynArray PRND(padSize); - PRND.random(); - toHash.set(&PRND, &dh_pubKey, &snIFDBa, &challenge, &dh_ICCpubKey, &dh_g, &dh_p, &dh_q); - ByteDynArray toHashBa = sha256.Digest(toHash); - toSign.set(0x6a, &PRND, &toHashBa, 0xBC); - - CRSA certKey(module, privexp); - - ByteDynArray signResp = certKey.RSA_PURE(toSign); - ByteDynArray chResponse; - chResponse.set(&snIFDBa, &signResp); - - uint8_t ExtAuth[] = { 0x00, 0x82, 0x00, 0x00 }; - if ((sw = SendAPDU_SM(VarToByteArray(ExtAuth), chResponse, resp)) != 0x9000) - throw scard_error(sw); - - - uint8_t IntAuth[] = { 0x00, 0x22, 0x41, 0xa4 }; - uint8_t Val82 = 0x82; - ByteArray IntAuthBa = VarToByteArray(IntAuth); - ByteArray Val82Ba = VarToByteArray(Val82); - ByteArray PKdSchemeBa = VarToByteArray(PKdScheme); - - if ((sw = SendAPDU_SM(VarToByteArray(IntAuth), ASN1Tag(0x84, Val82Ba).append(ASN1Tag(0x80, PKdSchemeBa)), resp)) != 0x9000) - throw scard_error(sw); - - ByteDynArray rndIFD(8); - rndIFD.random(); - uint8_t GiveRandom[] = { 0x00, 0x88, 0x00, 0x00 }; - if ((sw = SendAPDU_SM(VarToByteArray(GiveRandom), rndIFD, resp, 0)) != 0x9000) - throw scard_error(sw); - - ByteDynArray SN_ICC = resp.mid(0, 8); - - CRSA intAuthKey(DappModule, DappPubKey); - ByteArray respBa = resp.mid(8); - - ByteDynArray intAuthResp = intAuthKey.RSA_PURE(respBa); - ER_ASSERT(intAuthResp[0] == 0x6a, "Errore nell'autenticazione del chip"); - ByteArray PRND2 = intAuthResp.mid(1, intAuthResp.size() - 32 - 2); - ByteArray hashICC = intAuthResp.mid(PRND2.size() + 1, 32); - - ByteDynArray toHashIFD; - toHashIFD.set(&PRND2, &dh_ICCpubKey, &SN_ICC, &rndIFD, &dh_pubKey, &dh_g, &dh_p, &dh_q); - - ByteDynArray calcHashIFD = sha256.Digest(toHashIFD); - - ER_ASSERT(calcHashIFD == hashICC, "Errore nell'autenticazione del chip") - ER_ASSERT(intAuthResp.right(1)[0] == 0xbc, "Errore nell'autenticazione del chip"); - - ByteArray challengeBa = challenge.right(4); - ByteArray rndIFDBa = rndIFD.right(4); - sessSSC.set(&challengeBa, &rndIFDBa); - ActiveSM = true; - exit_func -} - -void IAS::DHKeyExchange() { - init_func - CASNParser asn1; - - ByteDynArray dh_prKey, secret, resp,d1; - do { - //Log.write("resize"); - dh_prKey.resize(dh_q.size()); - //Log.write("random"); - dh_prKey.random(); - - //Log.write("dh_q: %s", dumpHexData(dh_q).c_str()); - //Log.write("dh_prKey: %s", dumpHexData(dh_prKey).c_str()); - - //printf("dh_q: %s", dumpHexData(dh_q).c_str()); - //printf("dh_prKey: %s", dumpHexData(dh_prKey).c_str()); - - } while (dh_q[0] < dh_prKey[0]); - - // dh_prKey deve essere dispari - dh_prKey.right(1)[0] |= 1; - - ByteDynArray dhg(dh_g.size()); - dhg.fill(0); - dhg.rightcopy(dh_g); - CRSA rsa(dh_p, dh_prKey); - - dh_pubKey = rsa.RSA_PURE(dhg); - -// printf("\n\ndhpubKey: %s", dumpHexData(dh_pubKey).c_str()); - - uint8_t algo = 0x9b; - uint8_t keyId = CIE_KEY_DH_ID; - ByteArray algoBa = VarToByteArray(algo); - ByteArray keyIdBa = VarToByteArray(keyId); - - d1.setASN1Tag(0x80, algoBa).append(ASN1Tag(0x83, keyIdBa)).append(ASN1Tag(0x91, dh_pubKey)); - - uint8_t MSE_SET[] = { 0x00, 0x22, 0x41, 0xa6 }; - StatusWord sw; - if ((sw = SendAPDU(VarToByteArray(MSE_SET), d1, resp)) != 0x9000) - throw scard_error(sw); - uint8_t GET_DATA[] = { 0x00, 0xcb, 0x3f, 0xff }; - uint8_t GET_DATA_Data[] = { 0x4d, 0x04, 0xa6, 0x02, 0x91, 0x00 }; - if ((sw = SendAPDU(VarToByteArray(GET_DATA), VarToByteArray(GET_DATA_Data), resp)) != 0x9000) - throw scard_error(sw); - - asn1.Parse(resp); - dh_ICCpubKey = asn1.tags[0]->tags[0]->content; - -// printf("\ndhICCpubKey: %s", dumpHexData(dh_ICCpubKey).c_str()); - - secret = rsa.RSA_PURE(dh_ICCpubKey); - -// printf("\nsecret: %s", dumpHexData(secret).c_str()); - - CSHA256 sha256; - - uint8_t diffENC[] = { 0x00, 0x00, 0x00, 0x01 }; - uint8_t diffMAC[] = { 0x00, 0x00, 0x00, 0x02 }; - - sessENC = sha256.Digest(ByteDynArray(secret).append(VarToByteArray(diffENC))).left(16); - sessMAC = sha256.Digest(ByteDynArray(secret).append(VarToByteArray(diffMAC))).left(16); - -// printf("\nsessENC: %s", dumpHexData(sessENC).c_str()); -// printf("\nsessMAC: %s\n", dumpHexData(sessMAC).c_str()); - - sessSSC.resize(8); - sessSSC.fill(0); - sessSSC[7] = 1; - - ActiveSM = true; - exit_func -} - -void IAS::increment(ByteArray &seq) { - for (size_t i = seq.size() - 1; i >= 0; i--) { - if (seq[i] < 255) { - seq[i]++; - for (size_t j = i + 1; j < seq.size(); j++) - seq[j] = 0; - return; - } - } -} - - -ByteDynArray IAS::SM(ByteArray &keyEnc, ByteArray &keySig, ByteArray &apdu, ByteArray &seq) { - init_func - - std::string dmp; - ODS("%s", dumpHexData(seq, dmp).c_str()); - - increment(seq); - - ODS("%s", dumpHexData(seq, dmp).c_str()); - - ByteDynArray smHead; - smHead = apdu.left(4); - smHead[0] |= 0x0C; -// printf("apdu: %s\n", dumpHexData(smHead).c_str()); - - auto calcMac = ISOPad(ByteDynArray(seq).append(smHead)); - -// printf("calcMac: %s\n", dumpHexData(calcMac).c_str()); - - ByteDynArray iv(8); - iv.fill(0); // IV for APDU encryption and signature should be 0. Please refer to IAS specification §7.1.9 Secure messaging – Command APDU protection - -// printf("iv: %s\n", dumpHexData(iv).c_str()); - -// printf("keyEnc: %s\n", dumpHexData(keyEnc).c_str()); - CDES3 encDes(keyEnc, iv); - -// printf("keySig: %s\n", dumpHexData(keySig).c_str()); - - CMAC sigMac(keySig, iv); - - uint8_t Val01 = 1; -// uint8_t Val00 = 0; - - ByteDynArray datafield, doob; - if (apdu[4] != 0 && apdu.size() > 5) { - - ByteDynArray enc = encDes.RawEncode(ISOPad(apdu.mid(5, apdu[4]))); - -// printf("enc 1: %s\n", dumpHexData(enc).c_str()); - - if ((apdu[1] & 1) == 0) - doob.setASN1Tag(0x87, VarToByteDynArray(Val01).append(enc)); - else - doob.setASN1Tag(0x85, enc); - - calcMac.append(doob); - datafield.append(doob); - -// printf("calcMac 1: %s\n", dumpHexData(calcMac).c_str()); -// printf("datafield 1: %s\n", dumpHexData(datafield).c_str()); - } - if (apdu[4] == 0 && apdu.size() > 7) { - - ByteDynArray enc = encDes.RawEncode(ISOPad(apdu.mid(7, (apdu[5] << 8)| apdu[6] ))); - if ((apdu[1] & 1) == 0) - doob.setASN1Tag(0x87, VarToByteDynArray(Val01).append(enc)); - else - doob.setASN1Tag(0x85, enc); - - calcMac.append(doob); - datafield.append(doob); - -// printf("calcMac 2: %s\n", dumpHexData(calcMac).c_str()); -// printf("datafield 2: %s\n", dumpHexData(datafield).c_str()); - } - if (apdu.size() == 5 || apdu.size() == (apdu[4] + 6)) { - uint8_t le = apdu[apdu.size() - 1]; - ByteArray leBa = VarToByteArray(le); - doob.setASN1Tag(0x97, leBa); - calcMac.append(doob); - datafield.append(doob); - -// printf("calcMac 3: %s\n", dumpHexData(calcMac).c_str()); -// printf("datafield 3: %s\n", dumpHexData(datafield).c_str()); - } - - ByteDynArray macBa = sigMac.Mac(ISOPad(calcMac)); -// printf("macBa: %s\n", dumpHexData(macBa).c_str()); - - ByteDynArray tagMacBa = ASN1Tag(0x8e, macBa); -// printf("tagMacBa: %s\n", dumpHexData(tagMacBa).c_str()); - datafield.append(tagMacBa); - -// printf("datafield 4: %s\n", dumpHexData(datafield).c_str()); - - ByteDynArray elabResp; - if (datafield.size()<0x100) - elabResp.set(&smHead, (uint8_t)datafield.size(), &datafield, (uint8_t)0x00); - else { - auto len = datafield.size(); - auto lenBA = VarToByteArray(len); - ByteArray lenBa = lenBA.reverse().right(3); - - elabResp.set(&smHead, &lenBa, &datafield, (uint8_t)0x00, (uint8_t)0x00); - } - -// printf("elabResp: %s\n", dumpHexData(elabResp).c_str()); - return elabResp; -} - -StatusWord IAS::respSM(ByteArray &keyEnc, ByteArray &keySig, ByteArray &resp, ByteArray &seq, ByteDynArray &elabResp) { - init_func - - increment(seq); - DWORD index, llen, lgn; - StatusWord sw = 0xffff; - ByteDynArray encData; - ByteDynArray respMac, calcMac; - ByteDynArray iv(8); - iv.fill(0); // IV for APDU encryption should be 0. Please refer to IAS specification §7.1.9 Secure messaging – Command APDU protection - CDES3 encDes(keyEnc, iv); - CMAC sigMac(keySig, iv); - - calcMac = seq; - index = 0; - do { - - if (resp[index] == 0x99) { - calcMac.append(resp.mid(index, resp[index + 1] + 2)); - sw = resp[index + 2] << 8 | resp[index + 3]; - index += 4; - } else if (resp[index] == 0x8e) { - if (resp[index + 1] != 0x08) - throw logged_error("Lunghezza del MAC non valida"); - respMac = resp.mid(index + 2, 8); - index += 10; - } else if (resp[index] == 0x85) { - if (resp[index + 1] > 0x80) { - llen = resp[index + 1] - 0x80; - if (llen == 1) - lgn = resp[index + 2]; - else if (llen == 2) - lgn = (resp[index + 2] << 8) | resp[index + 3]; - else - throw logged_error(stdPrintf("Lunghezza ASN1 non valida: %i", llen)); - encData = resp.mid(index + llen + 2, lgn); - calcMac.append(resp.mid(index, lgn + llen + 2)); - index += llen + lgn + 2; - } else { - encData = resp.mid(index + 2, resp[index + 1]); - calcMac.append(resp.mid(index, resp[index + 1] + 2)); - index += resp[index + 1] + 2; - } - } else if (resp[index] == 0x87) { - if (resp[index + 1] > 0x80) { - llen = resp[index + 1] - 0x80; - if (llen == 1) - lgn = resp[index + 2]; - else if (llen == 2) - lgn = (resp[index + 2] << 8) | resp[index + 3]; - else - throw logged_error(stdPrintf("Lunghezza ASN1 non valida: %i", llen)); - encData = resp.mid(index + llen + 3, lgn - 1); - calcMac.append(resp.mid(index, lgn + llen + 2)); - index += llen + lgn + 2; - } else { - encData = resp.mid(index + 3, resp[index + 1] - 1); - calcMac.append(resp.mid(index, resp[index + 1] + 2)); - index += resp[index + 1] + 2; - } - } else - throw logged_error("Tag non riconosciuto nella risposta in Secure Messaging"); - } while (index < resp.size()); - - - auto smMac = sigMac.Mac(ISOPad(calcMac)); - ER_ASSERT(smMac == respMac,"Errore nel checksum della risposta del chip") - - if (!encData.isEmpty()) { - - elabResp=encDes.RawDecode(encData); - elabResp.resize(RemoveISOPad(elabResp),true); - } else - elabResp.clear(); - - return sw; -} - -StatusWord IAS::getResp(ByteDynArray &resp, StatusWord sw,ByteDynArray &elabresp) { - init_func - elabresp.clear(); - if (resp.size() != 0) - elabresp.append(resp); - - ByteDynArray curresp; - while (true) { - if ((sw >> 8) == 0x61) { - uint8_t ln = sw & 0xff; - if (ln != 0) { - uint8_t apdu[] = { 0x00, 0xc0, 0x00, 0x00, ln }; - sw = token.Transmit(VarToByteArray(apdu), &curresp); - elabresp.append(curresp); - return sw; - } else { - uint8_t apdu[] = { 0x00, 0xc0, 0x00, 0x00, 0x00 }; - sw = token.Transmit(VarToByteArray(apdu), &curresp); - elabresp.append(curresp); - } - } else { - return sw; - } - } - exit_func -} - -StatusWord IAS::getResp_SM(ByteArray &resp, StatusWord sw, ByteDynArray &elabresp) { - init_func - - - ByteDynArray s, ap; - CASNParser p; - elabresp.clear(); - if (resp.size() != 0) - elabresp.append(resp); - - ByteDynArray curresp; - while (true) { - if ((sw >> 8) == 0x61) { - uint8_t ln = sw & 0xff; - if (ln != 0) { - uint8_t apdu[] = { 0x00, 0xc0, 0x00, 0x00, ln }; - sw = token.Transmit(VarToByteArray(apdu), &curresp); - elabresp.append(curresp); - if (sw == 0x9000) - break; - if ((sw >> 8) != 0x61) - throw scard_error(sw); - } else { - uint8_t apdu[] = { 0x0c, 0xc0, 0x00, 0x00, 0x00 }; - sw = token.Transmit(VarToByteArray(apdu), &curresp); - elabresp.append(curresp); - } - } else if (sw == 0x9000 || sw == 0x6b00 || sw==0x6282) - break; - else - return sw; - } - return respSM(sessENC, sessMAC, elabresp, sessSSC, elabresp); - exit_func -} - - -StatusWord IAS::SendAPDU_SM(ByteArray head, ByteArray data, ByteDynArray &resp, uint8_t *le) { - init_func - ByteDynArray smApdu; - ByteDynArray s, curresp; - ByteArray emptyBa; - ByteArray leBa = VarToByteArray(*le); - std::string str; - - StatusWord sw; - if (data.size() < 0xE7) { - - smApdu.set(&head, (uint8_t)data.size(), &data, (le == nullptr) ? &emptyBa : &leBa); - - - ODS("%s", std::string().append("\nClear APDU:").append(dumpHexData(smApdu, str)).append("\n").c_str()); - smApdu = SM(sessENC, sessMAC, smApdu, sessSSC); - -// ODS("%s", std::string().append("\nAPDU:").append(dumpHexData(smApdu)).append("\n").c_str()); - - sw = token.Transmit(smApdu, &curresp); - -// ODS("%s", std::string().append("RESP:").append(dumpHexData(curresp)).append("\n").c_str()); - - sw = getResp_SM(curresp, sw, resp); - - - ODS("%s", std::string().append("Clear RESP:").append(dumpHexData(resp, str)).append(HexByte(sw >> 8)).append(HexByte(sw & 0xff)).append("\n").c_str()); - return sw; - } else { - // attenzione: - // in alcuni casi la carta ritorna 61xx fra un comando e l'altro in chaining. Questo è un grosso problema, perchè - // la get response sembra che faccia saltare il chaining. Forse è una questione di driver del lettore? - // Per daesso l'ho osservato solo su una virtual machine Win7 con il lettore in sharing con l'host - -//#define min -// size_t ds = data.size(); - size_t i = 0; - uint8_t cla = head[0]; - while (true) { - s = data.mid(i, min1(0xE7, data.size() - i)); - i += s.size(); - if (i != data.size()) - head[0] = cla | 0x10; - else - head[0] = cla; - if (s.size() != 0) - smApdu.set(&head, (BYTE)s.size(), &s, (le == nullptr || i < data.size()) ? &emptyBa : &leBa); - else - smApdu.set(&head, (le == nullptr || i < data.size()) ? &emptyBa : &leBa); - - ODS("%s", std::string("Clear APDU:").append(dumpHexData(smApdu, str)).append("\n").c_str()); - smApdu = SM(sessENC, sessMAC, smApdu, sessSSC); - -// ODS("%s", std::string().append("\nAPDU:").append(dumpHexData(smApdu)).append("\n").c_str()); - - sw = token.Transmit(smApdu, &curresp); - -// ODS("%s", std::string().append("\nRESP:").append(dumpHexData(curresp)).append("\n").c_str()); - - sw = getResp_SM(curresp, sw, resp); - - ODS("%s", std::string("Clear RESP:").append(dumpHexData(resp, str)).append(HexByte(sw >> 8)).append(HexByte(sw & 0xff)).append("\n").c_str()); - if (i == data.size()) - return sw; - } - - } - exit_func -} - - -StatusWord IAS::SendAPDU(ByteArray head, ByteArray data, ByteDynArray &resp, uint8_t *le) { - init_func - - ByteArray emptyBa; - ByteArray leBa = VarToByteArray(*le); - std::string str; - - ByteDynArray apdu, curresp; - auto ds = data.size(); - - if (ds > 255) { - size_t i = 0; - uint8_t cla = head[0]; - while (true) { - auto s = data.mid(i, min1(data.size()-i,255)); - i += s.size(); - if (i != data.size()) - head[0] = (cla | 0x10); - else - head[0] = cla; - - apdu.set(&head, (BYTE)s.size(), &s, le == nullptr ? &emptyBa : &leBa); - - StatusWord sw=token.Transmit(apdu, &curresp); - if (i == data.size()) { - sw = getResp(curresp, sw, resp); - - return sw; - } - } - } else { - if (data.size()!=0) - apdu.set(&head, (BYTE)data.size(), &data, le == nullptr ? &emptyBa : &leBa); - else - apdu.set(&head, le == nullptr ? &emptyBa : &leBa); - -// ODS("%s", std::string().append("\nAPDU:").append(dumpHexData(apdu)).append("\n").c_str()); - - StatusWord sw = token.Transmit(apdu, &curresp); - -// ODS("%s", std::string().append("RESP:").append(dumpHexData(curresp)).append("\n").c_str()); - - sw=getResp(curresp, sw, resp); - - return sw; - } - exit_func -} - - -void IAS::InitDHParam() { - init_func - ByteDynArray resp; - - CASNParser parser; - StatusWord sw; - - if (type == CIE_Type::CIE_Gemalto) { - uint8_t getDHDoup[] = { 00, 0xcb, 0x3f, 0xff }; - uint8_t getDHDuopData[] = { 0x4d, 0x08, 0x70, 0x06, 0xBF, 0xA1, 0x01, 0x02, 0xA3, 0x80 }; - - if ((sw = SendAPDU(VarToByteArray(getDHDoup), VarToByteArray(getDHDuopData), resp)) != 0x9000) - throw scard_error(sw); - - parser.Parse(resp); - - dh_g = parser.tags[0]->tags[0]->tags[0]->tags[0]->content; - dh_p = parser.tags[0]->tags[0]->tags[0]->tags[1]->content; - dh_q = parser.tags[0]->tags[0]->tags[0]->tags[2]->content; - } else if (type == CIE_Type::CIE_NXP || type == CIE_Type::CIE_STM || type == CIE_Type::CIE_STM2 || type == CIE_Type::CIE_STM3) { - uint8_t getDHDoup[] = { 00, 0xcb, 0x3f, 0xff }; - uint8_t getDHDuopData_g[] = { 0x4D, 0x0A, 0x70, 0x08, 0xBF, 0xA1, 0x01, 0x04, 0xA3, 0x02, 0x97, 0x00 }; - - if ((sw = SendAPDU(VarToByteArray(getDHDoup), VarToByteArray(getDHDuopData_g), resp)) != 0x9000) - throw scard_error(sw); - parser.Parse(resp); - dh_g = parser.tags[0]->tags[0]->tags[0]->tags[0]->content; - - uint8_t getDHDuopData_p[] = { 0x4D, 0x0A, 0x70, 0x08, 0xBF, 0xA1, 0x01, 0x04, 0xA3, 0x02, 0x98, 0x00 }; - if ((sw = SendAPDU(VarToByteArray(getDHDoup), VarToByteArray(getDHDuopData_p), resp)) != 0x9000) - throw scard_error(sw); - parser.Parse(resp); - dh_p = parser.tags[0]->tags[0]->tags[0]->tags[0]->content; - - uint8_t getDHDuopData_q[] = { 0x4D, 0x0A, 0x70, 0x08, 0xBF, 0xA1, 0x01, 0x04, 0xA3, 0x02, 0x99, 0x00 }; - if ((sw = SendAPDU(VarToByteArray(getDHDoup), VarToByteArray(getDHDuopData_q), resp)) != 0x9000) - throw scard_error(sw); - parser.Parse(resp); - dh_q = parser.tags[0]->tags[0]->tags[0]->tags[0]->content; - } else - throw logged_error("CIE non riconosciuta"); - - - exit_func -} - -CASNTag *GetTag(CASNTagArray &tags, DWORD id) { - for (std::size_t i = 0; i < tags.size(); i++) { - if (tags[i]->tagInt() == id) - return tags[i].get(); - } - return nullptr; -} - -void IAS::InitExtAuthKeyParam() { - init_func - ByteDynArray resp; - - uint8_t getKeyDoup[] = { 00, 0xcb, 0x3f, 0xff }; - uint8_t getKeyDuopData[] = { 0x4d, 0x09, 0x70, 0x07, 0xBF, 0xA0, CIE_KEY_ExtAuth_ID & 0x7f, 0x03, 0x7F, 0x49, 0x80 }; - StatusWord sw; - if ((sw = SendAPDU(VarToByteArray(getKeyDoup), VarToByteArray(getKeyDuopData), resp)) != 0x9000) - throw scard_error(sw); - - CASNParser parser; - parser.Parse(resp); - - CA_module = GetTag(parser.tags[0]->tags[0]->tags[0]->tags,0x81)->content; - CA_pubexp = GetTag(parser.tags[0]->tags[0]->tags[0]->tags, 0x82)->content; - CA_privexp = baExtAuth_PrivExp; - CA_CHR = GetTag(parser.tags[0]->tags[0]->tags[0]->tags, 0x5F20)->content; - CA_CHA = GetTag(parser.tags[0]->tags[0]->tags[0]->tags, 0x5F4C)->content; - CA_CAR = CA_CHR.mid(4); - CA_AID = CA_CHA.left(6); -} - -void IAS::SetCardContext(void* pCardData) { - token.setTransmitCallbackData(pCardData); -} - -void IAS::Deauthenticate() { - init_func - token.Reset(true); -} - -extern uint8_t encMod[]; -extern uint8_t encPriv[]; -extern uint8_t encPub[]; - -void IAS::InitEncKey() { - // uso la chiave di intAuth per i servizi per decifrare il certificato - init_func - std::string strPAN; - dumpHexData(PAN.mid(5, 6), strPAN, false); - - uint8_t mseSet[] = { 0x00, 0x22, 0x41, 0xa4 }; - uint8_t mseSetData[] = { 0x80, 0x01, 0x02, 0x84, 0x01, 0x83 }; - ByteDynArray resp; - StatusWord sw; - if (sessSSC.isEmpty()) { - if ((sw = SendAPDU(VarToByteArray(mseSet), VarToByteArray(mseSetData), resp)) != 0x9000) { - Log.writePure("sendapdu1 error: %x", sw); - throw scard_error(sw); - } - uint8_t intAuth[] = { 0x00, 0x88, 0x00, 0x00 }; - if ((sw = SendAPDU(VarToByteArray(intAuth), ByteArray((BYTE*)strPAN.c_str(), strPAN.length()), resp)) != 0x9000) { - Log.writePure("sendapdu2 error: %x", sw); - throw scard_error(sw); - } - } else { - if ((sw = SendAPDU_SM(VarToByteArray(mseSet), VarToByteArray(mseSetData), resp)) != 0x9000) { - Log.writePure("sendapdu3 error: %x", sw); - throw scard_error(sw); - } - uint8_t intAuth[] = { 0x00, 0x88, 0x00, 0x00 }; - if ((sw = SendAPDU_SM(VarToByteArray(intAuth), ByteArray((BYTE*)strPAN.c_str(), strPAN.length()), resp)) != 0x9000) { - Log.writePure("sendapdu4 error: %x", sw); - throw scard_error(sw); - } - } - - CSHA512 sha512; - auto cardSeed = sha512.Digest(resp); - CardEncKey = cardSeed.left(32); - CardEncIv= cardSeed.mid(32).left(16); -} - -void IAS::SetCache(const char *PAN, ByteArray &certificate, ByteArray &FirstPIN) { - init_func - ByteDynArray encCert, encPIN; - CAES enc(CardEncKey, CardEncIv); - - encCert=enc.Encode(certificate); - encPIN=enc.Encode(FirstPIN); - CacheSetData(PAN, encCert.data(), (int)encCert.size(), encPIN.data(), (int)encPIN.size()); -} - -int integrity = 0; -bool IsLowIntegrity() { -// if (integrity == 0) { -// -// HANDLE hToken; -// HANDLE hProcess; -// -// DWORD dwLengthNeeded; -// DWORD dwError = ERROR_SUCCESS; -// -// PTOKEN_MANDATORY_LABEL pTIL = NULL; -// DWORD dwIntegrityLevel; -// -// hProcess = GetCurrentProcess(); -// if (OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) -// { -// if (!GetTokenInformation(hToken, TokenIntegrityLevel, -// nullptr, 0, &dwLengthNeeded)) -// { -// dwError = GetLastError(); -// if (dwError == ERROR_INSUFFICIENT_BUFFER) -// { -// pTIL = (PTOKEN_MANDATORY_LABEL)LocalAlloc(0, -// dwLengthNeeded); -// if (pTIL != NULL) -// { -// if (GetTokenInformation(hToken, TokenIntegrityLevel, -// pTIL, dwLengthNeeded, &dwLengthNeeded)) -// { -// dwIntegrityLevel = *GetSidSubAuthority(pTIL->Label.Sid, -// (DWORD)(UCHAR)(*GetSidSubAuthorityCount(pTIL->Label.Sid) - 1)); -// -// if (dwIntegrityLevel == SECURITY_MANDATORY_LOW_RID) -// integrity = 1; -// else if (dwIntegrityLevel >= SECURITY_MANDATORY_MEDIUM_RID && -// dwIntegrityLevel < SECURITY_MANDATORY_HIGH_RID) -// integrity = 2; -// else if (dwIntegrityLevel >= SECURITY_MANDATORY_HIGH_RID) -// integrity = 3; -// else if (dwIntegrityLevel >= SECURITY_MANDATORY_SYSTEM_RID) -// integrity = 4; -// } -// LocalFree(pTIL); -// } -// } -// } -// CloseHandle(hToken); -// } -// } - return - integrity == 1; -} - - -void IAS::IconaSbloccoPIN() { - init_func - -} - -void IAS::GetFirstPIN(ByteDynArray &PIN) { - init_func - std::string PANStr; - dumpHexData(PAN.mid(5, 6), PANStr, false); - std::vector EncPINBuf; - CacheGetPIN(PANStr.c_str(), EncPINBuf); - - CAES enc(CardEncKey, CardEncIv); - PIN = enc.Decode(ByteArray(EncPINBuf.data(), EncPINBuf.size())); -} - -bool IAS::IsEnrolled() { - init_func - std::string PANStr; - dumpHexData(PAN.mid(5, 6), PANStr, false); - return CacheExists(PANStr.c_str()); -} - -bool IAS::IsEnrolled(const char* szPAN) { - init_func - - return CacheExists(szPAN); -} - -bool IAS::Unenroll() { - init_func - std::string PANStr; - dumpHexData(PAN.mid(5, 6), PANStr, false); - return CacheRemove(PANStr.c_str()); -} - -bool IAS::Unenroll(const char* szPAN) { - init_func - return CacheRemove(szPAN); -} - - -void IAS::GetCertificate(ByteDynArray &certificate,bool askEnable) { - init_func - if (!Certificate.isEmpty()) { - certificate = Certificate; - return; - } - - std::string PANStr; - dumpHexData(PAN.mid(5, 6), PANStr, false); - if (!CacheExists(PANStr.c_str())) { - - if (askEnable) { - - notifyCardNotRegistered(PANStr.c_str()); - //showUI(PANStr.c_str()); - - return; - } else { - certificate.clear(); - return; - } - } -// if (!CacheExists(PANStr.c_str())) -// throw logged_error("Errore in abilitazione CIE"); -// - - std::vector certEncBuf; - CacheGetCertificate(PANStr.c_str(), certEncBuf); - - CAES enc(CardEncKey, CardEncIv); - certificate = enc.Decode(ByteArray(certEncBuf.data(), certEncBuf.size())); - Certificate = certificate; -} - -uint8_t IAS::GetSODDigestAlg(ByteArray &SOD) { - CASNParser parser; - uint8_t OID_SHA512[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03 }; - uint8_t OID_SHA256[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 }; - - parser.Parse(SOD); - - std::string dump; - dumpHexData(SOD, dump); - - CASNTag &SODTag = *parser.tags[0]; - - CASNTag &temp = SODTag.Child(0, 0x30); - - CASNTag &temp2 = temp.Child(1, 0xA0).Child(0, 0x30); - - auto &digestAlgo = temp2.Child(1, 0x31).Child(0, 0x30).Child(0, 6).content; - - if (digestAlgo == VarToByteArray(OID_SHA256)) { - return 1; - } else if (digestAlgo == VarToByteArray(OID_SHA512)) { - return 2; - } else throw logged_error("Algoritmo di digest del SOD non supportato");; -} - -void IAS::VerificaSODPSS(ByteArray &SOD, std::map &hashSet) { - init_func - CASNParser parser; - parser.Parse(SOD); - - std::string dump; - dumpHexData(SOD, dump); - - CASNTag &SODTag = *parser.tags[0]; - - CASNTag &temp = SODTag.Child(0, 0x30); - - /* Verifica OID contentInfo */ - uint8_t OID[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02 }; - temp.Child(0, 06).Verify(VarToByteArray(OID)); - - uint8_t val3 = 3; - CASNTag &temp2 = temp.Child(1, 0xA0).Child(0, 0x30); - temp2.Child(0, 2).Verify(VarToByteArray(val3)); - - uint8_t OID_SHA512[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03 }; - temp2.Child(1, 0x31).Child(0, 0x30).Child(0, 6).Verify(VarToByteArray(OID_SHA512)); - - uint8_t OID3[] = { 0x67, 0x81, 0x08, 0x01, 0x01, 0x01 }; - temp2.Child(2, 0x30).Child(0, 06).Verify(VarToByteArray(OID3)); - - /* Prendo gli sha512 dei DG letti */ - ByteArray ttData = temp2.Child(2, 0x30).Child(1, 0xA0).Child(0, 04).content; - - CASNParser ttParser; - ttParser.Parse(ttData); - CASNTag &signedData = *ttParser.tags[0]; - signedData.CheckTag(0x30); - - /* Prendo il certificato del signer */ - CASNTag &signerCert = temp2.Child(3, 0xA0).Child(0, 0x30); - - CASNTag &temp3 = temp2.Child(4, 0x31).Child(0, 0x30); - uint8_t val1 = 1; - temp3.Child(0, 02).Verify(VarToByteArray(val1)); - - CASNTag &issuerName = temp3.Child(1, 0x30).Child(0, 0x30); - CASNTag &signerCertSerialNumber = temp3.Child(1, 0x30).Child(1, 02); - - temp3.Child(2, 0x30).Child(0, 06).Verify(VarToByteArray(OID_SHA512)); - - CASNTag &signerInfo = temp3.Child(3, 0xA0); - - uint8_t OID4[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x03 }; - signerInfo.Child(0, 0x30).Child(0, 06).Verify(VarToByteArray(OID4)); - - uint8_t OID5[] = { 0x67, 0x81, 0x08, 0x01, 0x01, 0x01 }; - signerInfo.Child(0, 0x30).Child(1, 0x31).Child(0, 06).Verify(VarToByteArray(OID5)); - - uint8_t OID6[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x04 }; - signerInfo.Child(1, 0x30).Child(0, 06).Verify(VarToByteArray(OID6)); - - CASNTag &digest = temp3.Child(3, 0xA0).Child(1, 0x30).Child(1, 0x31).Child(0, 04); - ByteArray digest_ = SOD.mid((int)digest.startPos, (int)(digest.endPos - digest.startPos)); - - uint8_t OID_RSAPSS[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0A }; - auto &signAlgo = temp3.Child(4, 0x30).Child(0, 06).content; - auto &digestAlgo = temp3.Child(4, 0x30).Child(1, 0x30).Child(0, 0xA0).Child(0, 0x30).Child(0, 06).content; - - if (digestAlgo != VarToByteArray(OID_SHA512)) - throw logged_error("Algoritmo del digest della firma non valido"); - if(signAlgo != VarToByteArray(OID_RSAPSS)) - throw logged_error("Algoritmo di firma non valido"); - - CSHA512 sha512; - ByteArray toHash = ttData.mid((int)signedData.startPos, (int)(signedData.endPos - signedData.startPos)); - ByteDynArray calcDigest_ = sha512.Digest(toHash); - - if (calcDigest_ != digest.content) - throw logged_error("Digest del SOD non corrispondente ai dati"); - - CASNTag &signature = temp3.Child(5, 04); - - ByteArray certRaw = SOD.mid((int)signerCert.startPos, (int)(signerCert.endPos - signerCert.startPos)); - - CryptoPP::ByteQueue certin; - certin.Put(certRaw.data(),certRaw.size()); - CryptoPP::ByteQueue pbKey; - CryptoPP::ByteQueue issuer; - CryptoPP::Integer serial; - - GetPublicKeyFromCert(certin, pbKey, issuer, serial); - -// long size = pbKey.CurrentSize(); -// BYTE* pbtPubKey = new BYTE[size]; -// pbKey.Get(pbtPubKey, size); -// -// ByteArray pubKeyData(pbtPubKey, pbKey.CurrentSize()); - - ByteDynArray pubKeyData(pbKey.CurrentSize()); - pbKey.Get(pubKeyData.data(), pubKeyData.size()); - - CASNParser pubKeyParser; - pubKeyParser.Parse(pubKeyData); - CASNTag &pubKey = *pubKeyParser.tags[0]->tags[1]; - - ByteArray content = pubKey.content; - - if(content.data()[0] == 0) // unsigned bits - content = content.mid(1); - - CASNParser pubKeyParser2; - pubKeyParser2.Parse(content); - CASNTag &pubKey2 = *pubKeyParser2.tags[0]; - - CASNTag &modTag = pubKey2.Child(0, 02); - ByteArray mod = modTag.content; - while (mod[0] == 0) - mod = mod.mid(1); - CASNTag &expTag = pubKey2.Child(1, 02); - ByteArray exp = expTag.content; - while (exp[0] == 0) - exp = exp.mid(1); - - ByteArray signatureData = signature.content; - - CRSA rsa(mod, exp); - - ByteArray toSign = SOD.mid((int)signerInfo.tags[0]->startPos, (int)(signerInfo.tags[signerInfo.tags.size() - 1]->endPos - signerInfo.tags[0]->startPos)); - - ByteDynArray toSignBa = toSign.getASN1Tag(0x31); - ByteArray ba(toSignBa.data(), toSignBa.size()); - - bool result = rsa.RSA_PSS(signatureData, ba); - - if (!result) { - throw logged_error("Firma del SOD non valida"); - } - - issuerName.Reparse(); - CASNParser issuerParser; - - ByteDynArray issuerBa(issuer.CurrentSize()); - issuer.Get(issuerBa.data(), issuerBa.size()); - - issuerParser.Parse(issuerBa); - - CASNTag &CertIssuer = *issuerParser.tags[0]; - if (issuerName.tags.size() != CertIssuer.tags.size()) -// throw logged_error("Issuer name non corrispondente"); - printf("Issuer name non corrispondente\n"); - - uint8_t val = 1; - signedData.Child(0, 02).Verify(VarToByteArray(val)); - signedData.Child(1, 0x30).Child(0, 06).Verify(VarToByteArray(OID_SHA512)); - - CASNTag &hashTag = signedData.Child(2, 0x30); - for (std::size_t i = 0; i 0) - { - log.Info("Verifica catena CSCA"); - X509CertChain chain = new X509CertChain(CSCA); - var certChain = chain.getPath(certDS); - if (certChain == null) - throw Exception("Il certificato di Document Signer non č valido"); - - var rootCert = certChain[0]; - if (!new ByteArray(rootCert.SubjectName.RawData).IsEqual(rootCert.IssuerName.RawData)) - throw Exception("Impossibile validare il certificato di Document Signer"); - } - */ - exit_func -} - -void IAS::VerificaSOD(ByteArray &SOD, std::map &hashSet) { - init_func - CASNParser parser; - parser.Parse(SOD); - - std::string dump; - dumpHexData(SOD, dump); - - CASNTag &SODTag = *parser.tags[0]; - - CASNTag &temp = SODTag.Child(0, 0x30); - uint8_t OID[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02 }; - - temp.Child(0, 06).Verify(VarToByteArray(OID)); - uint8_t val3=3; - CASNTag &temp2 = temp.Child(1, 0xA0).Child(0, 0x30); - temp2.Child(0, 2).Verify(VarToByteArray(val3)); - - uint8_t OID_SH256[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 }; - temp2.Child(1, 0x31).Child(0, 0x30).Child(0, 6).Verify(VarToByteArray(OID_SH256)); - - uint8_t OID3[] = { 0x67, 0x81, 0x08, 0x01, 0x01, 0x01 }; - temp2.Child(2, 0x30).Child(0, 06).Verify(VarToByteArray(OID3)); - ByteArray ttData = temp2.Child(2, 0x30).Child(1, 0xA0).Child(0, 04).content; - CASNParser ttParser; - ttParser.Parse(ttData); - CASNTag &signedData = *ttParser.tags[0]; - signedData.CheckTag(0x30); - - CASNTag &signerCert = temp2.Child(3, 0xA0).Child(0, 0x30); - - CASNTag &temp3 = temp2.Child(4, 0x31).Child(0, 0x30); - uint8_t val1 = 1; - temp3.Child(0, 02).Verify(VarToByteArray(val1)); - CASNTag &issuerName = temp3.Child(1, 0x30).Child(0, 0x30); -// CASNTag &signerCertSerialNumber = temp3.Child(1, 0x30).Child(1, 02); - temp3.Child(2, 0x30).Child(0, 06).Verify(VarToByteArray(OID_SH256)); - - CASNTag &signerInfo = temp3.Child(3, 0xA0); - - uint8_t OID4[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x03 }; - signerInfo.Child(0, 0x30).Child(0, 06).Verify(VarToByteArray(OID4)); - uint8_t OID5[] = { 0x67, 0x81, 0x08, 0x01, 0x01, 0x01 }; - signerInfo.Child(0, 0x30).Child(1, 0x31).Child(0, 06).Verify(VarToByteArray(OID5)); - uint8_t OID6[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x04 }; - signerInfo.Child(1, 0x30).Child(0, 06).Verify(VarToByteArray(OID6)); - CASNTag &digest = temp3.Child(3, 0xA0).Child(1, 0x30).Child(1, 0x31).Child(0, 04); - - uint8_t OID_RSAwithSHA256[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0b }; - uint8_t OID_RSAwithSHA1[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05 }; - auto &digestAlgo = temp3.Child(4, 0x30).Child(0, 06).content; - bool isSHA1 = false; - bool isSHA256 = false; - if (digestAlgo == VarToByteArray(OID_RSAwithSHA1)) - isSHA1 = true; - else if (digestAlgo == VarToByteArray(OID_RSAwithSHA256)) - isSHA256 = true; - else - throw logged_error("Algoritmo del digest della firma non valido"); - - CASNTag &signature = temp3.Child(5, 04); - - ByteArray toHash = ttData.mid((int)signedData.startPos, (int)(signedData.endPos - signedData.startPos)); - CSHA256 sha256; - ByteDynArray calcDigest = sha256.Digest(toHash); - if (calcDigest!=digest.content) - throw logged_error("Digest del SOD non corrispondente ai dati"); - - ByteArray certRaw = SOD.mid((int)signerCert.startPos, (int)(signerCert.endPos - signerCert.startPos)); - - - CryptoPP::ByteQueue certin; - certin.Put(certRaw.data(),certRaw.size()); - CryptoPP::ByteQueue pbKey; - CryptoPP::ByteQueue issuer; - CryptoPP::Integer serial; - - GetPublicKeyFromCert(certin, pbKey, issuer, serial); - -// long size = pbKey.CurrentSize(); -// BYTE* pbtPubKey = new BYTE[size]; -// pbKey.Get(pbtPubKey, size); -// -// ByteArray pubKeyData(pbtPubKey, pbKey.CurrentSize()); - - - - ByteDynArray pubKeyData(pbKey.CurrentSize()); - pbKey.Get(pubKeyData.data(), pubKeyData.size()); - - CASNParser pubKeyParser; - pubKeyParser.Parse(pubKeyData); - CASNTag &pubKey = *pubKeyParser.tags[0]->tags[1]; - - ByteArray content = pubKey.content; - - if(content.data()[0] == 0) // unsigned bits - content = content.mid(1); - - CASNParser pubKeyParser2; - pubKeyParser2.Parse(content); - CASNTag &pubKey2 = *pubKeyParser2.tags[0]; - - CASNTag &modTag = pubKey2.Child(0, 02); - ByteArray mod = modTag.content; - while (mod[0] == 0) - mod = mod.mid(1); - CASNTag &expTag = pubKey2.Child(1, 02); - ByteArray exp = expTag.content; - while (exp[0] == 0) - exp = exp.mid(1); - - ByteArray signatureData = signature.content; - - CRSA rsa(mod, exp); - - ByteDynArray decryptedSignature = rsa.RSA_PURE(signatureData); - decryptedSignature = decryptedSignature.mid(RemovePaddingBT1(decryptedSignature)); - - ByteArray toSign = SOD.mid((int)signerInfo.tags[0]->startPos, (int)(signerInfo.tags[signerInfo.tags.size()- 1]->endPos - signerInfo.tags[0]->startPos)); - - ByteDynArray digestSignature; - if (isSHA1) { - CSHA1 sha1; - decryptedSignature = decryptedSignature.mid(RemoveSha1(decryptedSignature)); - digestSignature = sha1.Digest(toSign.getASN1Tag(0x31)); - } - if (isSHA256) { - CSHA256 sha256; - decryptedSignature = decryptedSignature.mid(RemoveSha256(decryptedSignature)); - - ByteDynArray toSignBa = toSign.getASN1Tag(0x31); - ByteArray ba(toSignBa.data(), toSignBa.size()); - - digestSignature = sha256.Digest(ba); - - } - if (digestSignature!=decryptedSignature) - printf("Firma del SOD non valida"); -// throw logged_error("Firma del SOD non valida"); - - issuerName.Reparse(); - CASNParser issuerParser; - - ByteDynArray issuerBa(issuer.CurrentSize()); - issuer.Get(issuerBa.data(), issuerBa.size()); - - issuerParser.Parse(issuerBa); - - CASNTag &CertIssuer = *issuerParser.tags[0]; - if (issuerName.tags.size() != CertIssuer.tags.size()) -// throw logged_error("Issuer name non corrispondente"); - printf("Issuer name non corrispondente"); - - uint8_t val0=0; - signedData.Child(0, 02).Verify(VarToByteArray(val0)); - signedData.Child(1, 0x30).Child(0, 06).Verify(VarToByteArray(OID_SH256)); - - CASNTag &hashTag = signedData.Child(2, 0x30); - for (std::size_t i = 0; i 0) - { - log.Info("Verifica catena CSCA"); - X509CertChain chain = new X509CertChain(CSCA); - var certChain = chain.getPath(certDS); - if (certChain == null) - throw Exception("Il certificato di Document Signer non č valido"); - var rootCert = certChain[0]; - if (!new ByteArray(rootCert.SubjectName.RawData).IsEqual(rootCert.IssuerName.RawData)) - throw Exception("Impossibile validare il certificato di Document Signer"); - } - */ - exit_func -} - -#define DWL_MSGRESULT 0 - -//BOOL CheckOneInstance(char *nome) -//{ -// auto m_hStartEvent = CreateEvent(NULL, true, false, nome); -// if (GetLastError() == ERROR_ALREADY_EXISTS && m_hStartEvent != nullptr) { -// CloseHandle(m_hStartEvent); -// m_hStartEvent = nullptr; -// return FALSE; -// } -// return TRUE; -//} +#include "IAS.h" +#include "../Crypto/ASNParser.h" +#include "../Crypto/RSA.h" +#include "../Crypto/AES.h" +#include "../Crypto/sha256.h" +#include "../Crypto/sha512.h" +#include "../Crypto/SHA1.h" +#include "../Crypto/DES3.h" +#include "../Crypto/MAC.h" +#include +#include "../Util/ModuleInfo.h" +#include +#include +#include +#include + +//#include "../res/resource.h" +#include "../Util/CacheLib.h" +//#include +#include "../LOGGER/Logger.h" + +using namespace CieIDLogger; + +#define CIE_KEY_DH_ID 0x81 +#define CIE_KEY_ExtAuth_ID 0x84 +#define CIE_PIN_ID 0x81 +#define CIE_PUK_ID 0x82 +#define CIE_KEY_Sign_ID 0x81 + +#include +#include + +extern CLog Log; + +extern CModuleInfo moduleInfo; +extern ByteArray SkipZero(ByteArray &ba); +//extern DWORD WINAPI _abilitaCIE(LPVOID lpThreadParameter); + +void GetPublicKeyFromCert(CryptoPP::BufferedTransformation & certin, + CryptoPP::BufferedTransformation & keyout, + CryptoPP::BufferedTransformation & issuer, + CryptoPP::Integer &serial); + +void showUI(const char* szPAN); +void notifyCardNotRegistered(const char* szPAN); + +IAS::IAS(CToken::TokenTransmitCallback transmit,ByteArray ATR) { + init_func + + Callback = nullptr; + this->ATR = ATR; + uint8_t gemaltoAID[] = { 0xA0, 0x00, 0x00, 0x00, 0x30, 0x80, 0x00, 0x00, 0x00, 0x09, 0x81, 0x60, 0x01 }; + IAS_AID = VarToByteArray(gemaltoAID); + + uint8_t AID[] = { 0xA0, 0x00, 0x00, 0x00, 0x00, 0x39 }; + CIE_AID = VarToByteArray(AID); + + ActiveSM = false; + ActiveDF = DF_Root; + + token.setTransmitCallback(transmit, nullptr); +} + + +IAS::~IAS() { +} + +uint8_t defModule[] = { 0xba, 0x28, 0x37, 0xab, 0x4c, 0x6b, 0xb8, 0x27, 0x57, 0x7b, 0xff, 0x4e, 0xb7, 0xb1, 0xe4, 0x9c, 0xdd, 0xe0, 0xf1, 0x66, 0x14, 0xd1, 0xef, 0x24, 0xc1, 0xb7, 0x5c, 0xf7, 0x0f, 0xb1, 0x2c, 0xd1, 0x8f, 0x4d, 0x14, 0xe2, 0x81, 0x4b, 0xa4, 0x87, 0x7e, 0xa8, 0x00, 0xe1, 0x75, 0x90, 0x60, 0x76, 0xb5, 0x62, 0xba, 0x53, 0x59, 0x73, 0xc5, 0xd8, 0xb3, 0x78, 0x05, 0x1d, 0x8a, 0xfc, 0x74, 0x07, 0xa1, 0xd9, 0x19, 0x52, 0x9e, 0x03, 0xc1, 0x06, 0xcd, 0xa1, 0x8d, 0x69, 0x9a, 0xfb, 0x0d, 0x8a, 0xb4, 0xfd, 0xdd, 0x9d, 0xc7, 0x19, 0x15, 0x9a, 0x50, 0xde, 0x94, 0x68, 0xf0, 0x2a, 0xb1, 0x03, 0xe2, 0x82, 0xa5, 0x0e, 0x71, 0x6e, 0xc2, 0x3c, 0xda, 0x5b, 0xfc, 0x4a, 0x23, 0x2b, 0x09, 0xa4, 0xb2, 0xc7, 0x07, 0x45, 0x93, 0x95, 0x49, 0x09, 0x9b, 0x44, 0x83, 0xcb, 0xae, 0x62, 0xd0, 0x09, 0x96, 0x74, 0xdb, 0xf6, 0xf3, 0x9b, 0x72, 0x23, 0xa9, 0x9d, 0x88, 0xe3, 0x3f, 0x1a, 0x0c, 0xde, 0xde, 0xeb, 0xbd, 0xc3, 0x55, 0x17, 0xab, 0xe9, 0x88, 0x0a, 0xab, 0x24, 0x0e, 0x1e, 0xa1, 0x66, 0x28, 0x3a, 0x27, 0x4a, 0x9a, 0xd9, 0x3b, 0x4b, 0x1d, 0x19, 0xf3, 0x67, 0x9f, 0x3e, 0x8b, 0x5f, 0xf6, 0xa1, 0xe0, 0xed, 0x73, 0x6e, 0x84, 0xd5, 0xab, 0xe0, 0x3c, 0x59, 0xe7, 0x34, 0x6b, 0x42, 0x18, 0x75, 0x5d, 0x75, 0x36, 0x6c, 0xbf, 0x41, 0x36, 0xf0, 0xa2, 0x6c, 0x3d, 0xc7, 0x0a, 0x69, 0xab, 0xaa, 0xf6, 0x6e, 0x13, 0xa1, 0xb2, 0xfa, 0xad, 0x05, 0x2c, 0xa6, 0xec, 0x9c, 0x51, 0xe2, 0xae, 0xd1, 0x4d, 0x16, 0xe0, 0x90, 0x25, 0x4d, 0xc3, 0xf6, 0x4e, 0xa2, 0xbd, 0x8a, 0x83, 0x6b, 0xba, 0x99, 0xde, 0xfa, 0xcb, 0xa3, 0xa6, 0x13, 0xae, 0xed, 0xd9, 0x3a, 0x96, 0x15, 0x27, 0x3d }; +uint8_t defPrivExp[] = { 0x47, 0x16, 0xc2, 0xa3, 0x8c, 0xcc, 0x7a, 0x07, 0xb4, 0x15, 0xeb, 0x1a, 0x61, 0x75, 0xf2, 0xaa, 0xa0, 0xe4, 0x9c, 0xea, 0xf1, 0xba, 0x75, 0xcb, 0xa0, 0x9a, 0x68, 0x4b, 0x04, 0xd8, 0x11, 0x18, 0x79, 0xd3, 0xe2, 0xcc, 0xd8, 0xb9, 0x4d, 0x3c, 0x5c, 0xf6, 0xc5, 0x57, 0x53, 0xf0, 0xed, 0x95, 0x87, 0x91, 0x0b, 0x3c, 0x77, 0x25, 0x8a, 0x01, 0x46, 0x0f, 0xe8, 0x4c, 0x2e, 0xde, 0x57, 0x64, 0xee, 0xbe, 0x9c, 0x37, 0xfb, 0x95, 0xcd, 0x69, 0xce, 0xaf, 0x09, 0xf4, 0xb1, 0x35, 0x7c, 0x27, 0x63, 0x14, 0xab, 0x43, 0xec, 0x5b, 0x3c, 0xef, 0xb0, 0x40, 0x3f, 0x86, 0x8f, 0x68, 0x8e, 0x2e, 0xc0, 0x9a, 0x49, 0x73, 0xe9, 0x87, 0x75, 0x6f, 0x8d, 0xa7, 0xa1, 0x01, 0xa2, 0xca, 0x75, 0xa5, 0x4a, 0x8c, 0x4c, 0xcf, 0x9a, 0x1b, 0x61, 0x47, 0xe4, 0xde, 0x56, 0x42, 0x3a, 0xf7, 0x0b, 0x20, 0x67, 0x17, 0x9c, 0x5e, 0xeb, 0x64, 0x68, 0x67, 0x86, 0x34, 0x78, 0xd7, 0x52, 0xc7, 0xf4, 0x12, 0xdb, 0x27, 0x75, 0x41, 0x57, 0x5a, 0xa0, 0x61, 0x9d, 0x30, 0xbc, 0xcc, 0x8d, 0x87, 0xe6, 0x17, 0x0b, 0x33, 0x43, 0x9a, 0x2c, 0x93, 0xf2, 0xd9, 0x7e, 0x18, 0xc0, 0xa8, 0x23, 0x43, 0xa6, 0x01, 0x2a, 0x5b, 0xb1, 0x82, 0x28, 0x08, 0xf0, 0x1b, 0x5c, 0xfd, 0x85, 0x67, 0x3a, 0xc0, 0x96, 0x4c, 0x5f, 0x3c, 0xfd, 0x2d, 0xaf, 0x81, 0x42, 0x35, 0x97, 0x64, 0xa9, 0xad, 0xb9, 0xe3, 0xf7, 0x6d, 0xb6, 0x13, 0x46, 0x1c, 0x1b, 0xc9, 0x13, 0xdc, 0x9a, 0xc0, 0xab, 0x50, 0xd3, 0x65, 0xf7, 0x7c, 0xb9, 0x31, 0x94, 0xc9, 0x8a, 0xa9, 0x66, 0xd8, 0x9c, 0xdd, 0x55, 0x51, 0x25, 0xa5, 0xe5, 0x9e, 0xcf, 0x4f, 0xa3, 0xf0, 0xc3, 0xfd, 0x61, 0x0c, 0xd3, 0xd0, 0x56, 0x43, 0x93, 0x38, 0xfd, 0x81 }; +uint8_t defPubExp[] = { 0x00, 0x01, 0x00, 0x01 }; + +void IAS::ReadSOD(ByteDynArray &data) { + init_func + readfile(0x1006,data); + LOG_DEBUG("SOD:"); + LOG_BUFFER(data.data(), data.size()); + exit_func +} +void IAS::ReadDH(ByteDynArray &data) { + init_func + readfile(0xd004, data); + + LOG_DEBUG("ReadDH - Data:"); + LOG_BUFFER(data.data(), data.size()); + exit_func +} +void IAS::ReadCertCIE(ByteDynArray &data) { + init_func + readfile(0x1003, data); + + LOG_DEBUG("ReadCertCIE - Cert CIE:"); + LOG_BUFFER(data.data(), data.size()); + exit_func +} +void IAS::ReadServiziPubKey(ByteDynArray &data) { + init_func + readfile(0x1005, data); + + LOG_DEBUG("ReadServiziPubKey - Data:"); + LOG_BUFFER(data.data(), data.size()); + exit_func +} +void IAS::ReadSerialeCIE(ByteDynArray &data) { + init_func + readfile(0x1002, data); + + LOG_DEBUG("ReadSerialeCIE - CIE serial number:"); + LOG_BUFFER(data.data(), data.size()); + exit_func +} +void IAS::ReadIdServizi(ByteDynArray &data) { + init_func + readfile(0x1001, data); + + LOG_DEBUG("ReadIdServizi - CIE Id Servizi:"); + LOG_BUFFER(data.data(), data.size()); + exit_func +} + +void IAS::Sign(ByteArray &data, ByteDynArray &signedData) { + init_func + ByteDynArray resp; + uint8_t SetKey[] = { 0x00, 0x22, 0x41, 0xA4 }; + uint8_t val02 = 2; + uint8_t keyId = CIE_KEY_Sign_ID; + + LOG_DEBUG("IAS::Sign - Buffer to sign:"); + LOG_BUFFER(data.data(), data.size()); + + StatusWord sw; + ByteArray val02Ba = VarToByteArray(val02); + ByteArray keyIdBa = VarToByteArray(keyId); + if ((sw = SendAPDU_SM(VarToByteArray(SetKey), ASN1Tag(0x80, val02Ba).append(ASN1Tag(0x84, keyIdBa)), resp)) != 0x9000) { + LOG_ERROR("IAS::Sign - Smart card response error"); + throw scard_error(sw); + } + + uint8_t Sign[] = { 0x00, 0x88, 0x00, 0x00 }; + if ((sw = SendAPDU_SM(VarToByteArray(Sign), data, signedData)) != 0x9000) { + LOG_ERROR("IAS::Sign error!"); + throw scard_error(sw); + } + +} + +StatusWord IAS::VerifyPUK(ByteArray &PIN) { + init_func + ByteDynArray resp; + + LOG_DEBUG("IAS::VerifyPUK"); + uint8_t verifyPIN[] = { 0x00, 0x20, 0x00, CIE_PUK_ID }; + return SendAPDU_SM(VarToByteArray(verifyPIN), PIN, resp); +} + +StatusWord IAS::VerifyPIN(ByteArray &PIN) { + init_func + ByteDynArray resp; + + LOG_DEBUG("IAS::VerifyPIN"); + uint8_t verifyPIN[] = { 0x00, 0x20, 0x00, CIE_PIN_ID }; + return SendAPDU_SM(VarToByteArray(verifyPIN), PIN, resp); + exit_func +} + +StatusWord IAS::UnblockPIN() { + init_func + ByteDynArray resp; + + LOG_DEBUG("IAS::UnblockPIN"); + uint8_t UnblockPIN[] = { 0x00, 0x2C, 0x03, CIE_PIN_ID }; + return SendAPDU_SM(VarToByteArray(UnblockPIN), ByteArray(), resp); + exit_func +} + +StatusWord IAS::ChangePIN(ByteArray &oldPIN,ByteArray &newPIN) { + init_func + ByteDynArray resp; + ByteDynArray data=oldPIN; + data.append(newPIN); + uint8_t ChangePIN[] = { 0x00, 0x24, 0x00, CIE_PIN_ID }; + return SendAPDU_SM(VarToByteArray(ChangePIN), data, resp); + exit_func +} + +StatusWord IAS::ChangePIN(ByteArray &newPIN) { + init_func + ByteDynArray resp; + + LOG_DEBUG("IAS::ChangePIN"); + uint8_t ChangePIN[] = { 0x00, 0x2C, 0x02, CIE_PIN_ID }; + return SendAPDU_SM(VarToByteArray(ChangePIN), newPIN, resp); + exit_func +} + +void IAS::readfile(uint16_t id, ByteDynArray &content) { + init_func + + LOG_DEBUG("IAS::readfile - id: %d", id); + LOG_DEBUG("IAS::readfile - is SM Active: %d", ActiveSM); + + if (ActiveSM) + return readfile_SM(id, content); + + ByteDynArray resp; + uint8_t selectFile[] = { 0x00, 0xa4, 0x02, 0x04 }; + uint8_t fileId[] = { HIBYTE(id), LOBYTE(id) }; + StatusWord sw; + if ((sw = SendAPDU(VarToByteArray(selectFile), VarToByteArray(fileId), resp)) != 0x9000) + throw scard_error(sw); + + + WORD cnt = 0; + uint8_t chunk = 128; + while (true) { + ByteDynArray chn; + uint8_t readFile[] = { 0x00, 0xb0, HIBYTE(cnt), LOBYTE(cnt) }; + sw = SendAPDU(VarToByteArray(readFile), ByteArray(), chn, &chunk); + if ((sw >> 8) == 0x6c) { + uint8_t le = sw & 0xff; + sw = SendAPDU(VarToByteArray(readFile), ByteArray(), chn, &le); + } + if (sw == 0x9000) { + content.append(chn); + cnt = content.size(); +// WORD chnSize; +// if (FAILED(SizeTToWord(chn.size(), &chnSize)) || FAILED(WordAdd(cnt, chnSize, &cnt))) +// throw logged_error("File troppo grande"); + chunk = 128; + } else { + if (sw == 0x6282) + content.append(chn); + else if (sw != 0x6b00) + throw scard_error(sw); + break; + } + } + exit_func +} + +void IAS::readfile_SM(uint16_t id, ByteDynArray &content) { + init_func + + ByteDynArray resp; + uint8_t selectFile[] = { 0x00, 0xa4, 0x02, 0x04 }; + uint8_t fileId[] = { HIBYTE(id), LOBYTE(id) }; + StatusWord sw; + if ((sw = SendAPDU_SM(VarToByteArray(selectFile), VarToByteArray(fileId), resp)) != 0x9000) + throw scard_error(sw); + + + WORD cnt = 0; + uint8_t chunk = 128; + while (true) { + ByteDynArray chn; + uint8_t readFile[] = { 0x00, 0xb0, HIBYTE(cnt), LOBYTE(cnt) }; + sw = SendAPDU_SM(VarToByteArray(readFile), ByteArray(), chn, &chunk); + if ((sw >> 8) == 0x6c) { + uint8_t le = sw & 0xff; + sw = SendAPDU_SM(VarToByteArray(readFile), ByteArray(), chn, &le); + } + if (sw == 0x9000) { + content.append(chn); + cnt = content.size(); +// WORD chnSize; +// if (FAILED(SizeTToWord(chn.size(), &chnSize)) || FAILED(WordAdd(cnt, chnSize, &cnt))) +// throw logged_error("File troppo grande"); + chunk = 128; + } else { + if (sw == 0x6282) + content.append(chn); + else if (sw != 0x6b00) + throw scard_error(sw); + break; + } + } + exit_func +} + +void IAS::SelectAID_CIE(bool SM) { + init_func + ByteDynArray resp; + uint8_t selectCIE[] = { 0x00, 0xa4, 0x04, 0x0c }; + ByteDynArray selectCIEapdu; + StatusWord sw; + + LOG_DEBUG("IAS::SelectAID_CIE"); + if (SM) { + if ((sw = SendAPDU_SM(VarToByteArray(selectCIE), CIE_AID, resp)) != 0x9000) + throw scard_error(sw); + } else { + if ((sw = SendAPDU(VarToByteArray(selectCIE), CIE_AID, resp)) != 0x9000) + throw scard_error(sw); + } + ActiveDF = DF_CIE; + ActiveSM = false; + exit_func +} + +uint8_t NXP_ATR[] = { 0x80, 0x31, 0x80, 0x65, 0x49, 0x54, 0x4E, 0x58, 0x50 }; +uint8_t Gemalto_ATR[] = { 0x80, 0x31, 0x80, 0x65, 0xB0, 0x85, 0x04, 0x00, 0x11 }; +uint8_t Gemalto2_ATR[] = { 0x80, 0x31, 0x80, 0x65, 0xB0, 0x85, 0x03, 0x00, 0xEF }; +uint8_t STM_ATR[] = {0x80, 0x66, 0x47, 0x50, 0x00, 0xB8, 0x00, 0x7F}; +uint8_t STM2_ATR[] = { 0x80, 0x80, 0x01, 0x01 }; +uint8_t STM3_ATR[] = { 0x80, 0x01, 0x80, 0x66, 0x47, 0x50, 0x00, 0xB8, 0x00, 0x94, 0x82, 0x90, 0x00, 0xC5 }; + +ByteArray baNXP_ATR(NXP_ATR, sizeof(NXP_ATR)); +ByteArray baGemalto_ATR(Gemalto_ATR, sizeof(Gemalto_ATR)); +ByteArray baGemalto2_ATR(Gemalto2_ATR, sizeof(Gemalto2_ATR)); +ByteArray baSTM_ATR(STM_ATR, sizeof(STM_ATR)); +ByteArray baSTM2_ATR(STM2_ATR, sizeof(STM2_ATR)); +ByteArray baSTM3_ATR(STM3_ATR, sizeof(STM3_ATR)); + +void IAS::ReadCIEType() { + init_func + size_t position; + if (ATR.indexOf(baNXP_ATR, position)) { + type = CIE_Type::CIE_NXP; + LOG_INFO("IAS::ReadCIEType - CIE NXP detected"); + } else if (ATR.indexOf(baGemalto_ATR, position)) { + type = CIE_Type::CIE_Gemalto; + LOG_INFO("IAS::ReadCIEType - CIE Gemalto detected\n"); + } else if (ATR.indexOf(baGemalto2_ATR, position)) { + type = CIE_Type::CIE_Gemalto; + LOG_INFO("IAS::ReadCIEType - CIE Gemalto2 detected\n"); + } else if (ATR.indexOf(baSTM_ATR, position)) { + type = CIE_Type::CIE_STM; + LOG_INFO("IAS::ReadCIEType - CIE STM detected\n"); + } else if (ATR.indexOf(baSTM2_ATR, position)) { + type = CIE_Type::CIE_STM2; + LOG_INFO("IAS::ReadCIEType - CIE STM2 detected\n"); + } else if (ATR.indexOf(baSTM3_ATR, position)) { + type = CIE_Type::CIE_STM3; + LOG_INFO("IAS::ReadCIEType - CIE STM3 detected\n"); + } else + throw logged_error("IAS::ReadCIEType - CIE not recognized"); +} + +void IAS::SelectAID_IAS(bool SM) { + init_func + if (type == CIE_Type::CIE_Unknown) { + ReadCIEType(); + } + ByteDynArray resp; + StatusWord sw; + + if (type == CIE_Type::CIE_NXP) { + uint8_t selectMF[] = { 0x00, 0xa4, 0x00, 0x00 }; + + if (SM) { + if ((sw = SendAPDU_SM(VarToByteArray(selectMF), ByteArray(), resp)) != 0x9000) + throw scard_error(sw); + } else { + if ((sw = SendAPDU(VarToByteArray(selectMF), ByteArray(), resp)) != 0x9000) + throw scard_error(sw); + } + } else if (type == CIE_Type::CIE_Gemalto || type == CIE_Type::CIE_STM || CIE_Type::CIE_STM2 || CIE_Type::CIE_STM3) { + uint8_t selectIAS[] = { 0x00, 0xa4, 0x04, 0x0c }; + if (SM) { + if ((sw = SendAPDU_SM(VarToByteArray(selectIAS), IAS_AID, resp)) != 0x9000) + throw scard_error(sw); + } else { + if ((sw = SendAPDU(VarToByteArray(selectIAS), IAS_AID, resp)) != 0x9000) + throw scard_error(sw); + } + } else { + throw logged_error("Tipo CIE sconosciuto"); + } + + SM = false; + + ActiveDF = DF_IAS; + ActiveSM = false; + exit_func +} + +void IAS::ReadDappPubKey(ByteDynArray &DappKey) { + init_func + + LOG_DEBUG("**** Starting ReadDappPubKey *****"); + + ByteDynArray resp; + readfile(0x1004, DappKey); + + CASNParser parser; + parser.Parse(DappKey); + LOG_DEBUG("ReadDappPubKey - Parsing ok"); + ByteArray module = parser.tags[0]->tags[0]->content; + while (module[0] == 0) + module = module.mid(1); + DappModule = module; + ByteArray pubKey = parser.tags[0]->tags[1]->content; + while (pubKey[0] == 0) + pubKey = pubKey.mid(1); + DappPubKey = pubKey; + + LOG_DEBUG("ReadDappPubKey - Pub Key:"); + LOG_BUFFER(DappPubKey.data(), DappPubKey.size()); + + LOG_DEBUG("**** ReadDappPubKey Completed *****"); + exit_func +} + +void IAS::ReadPAN() { + init_func + readfile(0xd003, PAN); + + LOG_DEBUG("ReadPAN - PAN:"); + LOG_BUFFER(PAN.data(), PAN.size()); + exit_func +} + +void IAS::DAPP() { + init_func + + ByteDynArray resp; + uint8_t psoVerifyAlgo = 0x41; + uint8_t PKdScheme = 0x9B; + uint8_t shaOID = 0x04; + DWORD shaSize = 32; + CSHA256 sha256; +// uint8_t Val01 = 1; + + if (DappPubKey.isEmpty()) { + throw logged_error("DAPP - DAPP key not available"); + } + + ByteDynArray module = VarToByteArray(defModule); + ByteDynArray pubexp = VarToByteArray(defPubExp); + ByteDynArray privexp = VarToByteArray(defPrivExp); + + ByteDynArray cert; + ByteDynArray CHR, CHA, OID; + + + uint8_t snIFD[] = { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }; + uint8_t CPI=0x8A; + uint8_t baseCHR[] = { 0x00, 0x00, 0x00, 0x00 }; + + ByteArray baseCHRBa = VarToByteArray(baseCHR); + ByteArray snIFDBa = VarToByteArray(snIFD); + + CHR.set(&baseCHRBa, &snIFDBa); + CHA.set(&CA_AID,01); + uint8_t baseOID[] = { 0x2A, 0x81, 0x22, 0xF4, 0x2A, 0x02, 0x04, 0x01 }; + + ByteArray baseOIDBa = VarToByteArray(baseOID); + OID.set(&baseOIDBa, shaOID); + + ByteDynArray endEntityCert; + endEntityCert.set(CPI, &CA_CAR, &CHR, &CHA, &OID, &module, &pubexp); + + ByteDynArray certSign, toSign; +// uint8_t ValBC = 0xBC; + + ByteArray endEntityCertBa = endEntityCert.left(CA_module.size() - shaSize - 2); + + ByteDynArray endEntityCertDigestBa = sha256.Digest(endEntityCert); + + toSign.set(0x6A, &endEntityCertBa, &endEntityCertDigestBa, 0xbc); + CRSA caKey(CA_module, CA_privexp); + + certSign = caKey.RSA_PURE(toSign); + + ByteDynArray certVerif; + CRSA caPubKey(CA_module, CA_pubexp); + + certVerif = caPubKey.RSA_PURE(certSign); + ER_ASSERT(certVerif == toSign, "Errore in verifica firma!") + + ByteDynArray PkRem; + PkRem = endEntityCert.mid(CA_module.size() - shaSize - 2); + + cert.setASN1Tag(0x7F21, ASN1Tag(0x5F37, certSign).append(ASN1Tag(0x5F38, PkRem)).append(ASN1Tag(0x42, CA_CAR))); + + uint8_t SelectKey[] = { 0x00, 0x22, 0x81, 0xb6 }; + uint8_t id = CIE_KEY_ExtAuth_ID; + StatusWord sw; + + uint8_t le = 0; + ByteArray psoVerifyAlgoBa = VarToByteArray(psoVerifyAlgo); + ByteArray idBa = VarToByteArray(id); + if ((sw = SendAPDU_SM(VarToByteArray(SelectKey), ASN1Tag(0x80, psoVerifyAlgoBa).append(ASN1Tag(0x83, idBa)), resp, &le)) != 0x9000) + throw scard_error(sw); + + uint8_t VerifyCert[] = { 0x00, 0x2A, 0x00, 0xAE }; + if ((sw = SendAPDU_SM(VarToByteArray(VerifyCert), cert, resp)) != 0x9000) + throw scard_error(sw); + + uint8_t SetCHR[] = { 0x00, 0x22, 0x81, 0xA4 }; + + if ((sw = SendAPDU_SM(VarToByteArray(SetCHR), ASN1Tag(0x83, CHR), resp)) != 0x9000) + throw scard_error(sw); + + ByteDynArray challenge; + uint8_t GetChallenge[] = { 0x00, 0x84, 0x00, 0x00 }; + uint8_t chLen = 8; + + if ((sw = SendAPDU_SM(VarToByteArray(GetChallenge), ByteArray(), challenge, &chLen)) != 0x9000) + throw scard_error(sw); + + ByteDynArray toHash; + size_t padSize = module.size() - shaSize - 2; + ByteDynArray PRND(padSize); + PRND.random(); + toHash.set(&PRND, &dh_pubKey, &snIFDBa, &challenge, &dh_ICCpubKey, &dh_g, &dh_p, &dh_q); + ByteDynArray toHashBa = sha256.Digest(toHash); + toSign.set(0x6a, &PRND, &toHashBa, 0xBC); + + CRSA certKey(module, privexp); + + ByteDynArray signResp = certKey.RSA_PURE(toSign); + ByteDynArray chResponse; + chResponse.set(&snIFDBa, &signResp); + + uint8_t ExtAuth[] = { 0x00, 0x82, 0x00, 0x00 }; + if ((sw = SendAPDU_SM(VarToByteArray(ExtAuth), chResponse, resp)) != 0x9000) + throw scard_error(sw); + + + uint8_t IntAuth[] = { 0x00, 0x22, 0x41, 0xa4 }; + uint8_t Val82 = 0x82; + ByteArray IntAuthBa = VarToByteArray(IntAuth); + ByteArray Val82Ba = VarToByteArray(Val82); + ByteArray PKdSchemeBa = VarToByteArray(PKdScheme); + + if ((sw = SendAPDU_SM(VarToByteArray(IntAuth), ASN1Tag(0x84, Val82Ba).append(ASN1Tag(0x80, PKdSchemeBa)), resp)) != 0x9000) + throw scard_error(sw); + + ByteDynArray rndIFD(8); + rndIFD.random(); + uint8_t GiveRandom[] = { 0x00, 0x88, 0x00, 0x00 }; + if ((sw = SendAPDU_SM(VarToByteArray(GiveRandom), rndIFD, resp, 0)) != 0x9000) + throw scard_error(sw); + + ByteDynArray SN_ICC = resp.mid(0, 8); + + CRSA intAuthKey(DappModule, DappPubKey); + ByteArray respBa = resp.mid(8); + + ByteDynArray intAuthResp = intAuthKey.RSA_PURE(respBa); + ER_ASSERT(intAuthResp[0] == 0x6a, "Errore nell'autenticazione del chip"); + ByteArray PRND2 = intAuthResp.mid(1, intAuthResp.size() - 32 - 2); + ByteArray hashICC = intAuthResp.mid(PRND2.size() + 1, 32); + + ByteDynArray toHashIFD; + toHashIFD.set(&PRND2, &dh_ICCpubKey, &SN_ICC, &rndIFD, &dh_pubKey, &dh_g, &dh_p, &dh_q); + + ByteDynArray calcHashIFD = sha256.Digest(toHashIFD); + + ER_ASSERT(calcHashIFD == hashICC, "Errore nell'autenticazione del chip") + ER_ASSERT(intAuthResp.right(1)[0] == 0xbc, "Errore nell'autenticazione del chip"); + + ByteArray challengeBa = challenge.right(4); + ByteArray rndIFDBa = rndIFD.right(4); + sessSSC.set(&challengeBa, &rndIFDBa); + ActiveSM = true; + exit_func +} + +void IAS::DHKeyExchange() { + init_func + CASNParser asn1; + + ByteDynArray dh_prKey, secret, resp,d1; + do { + dh_prKey.resize(dh_q.size()); + dh_prKey.random(); + } while (dh_q[0] < dh_prKey[0]); + + // dh_prKey deve essere dispari + dh_prKey.right(1)[0] |= 1; + + ByteDynArray dhg(dh_g.size()); + dhg.fill(0); + dhg.rightcopy(dh_g); + CRSA rsa(dh_p, dh_prKey); + + dh_pubKey = rsa.RSA_PURE(dhg); + +// printf("\n\ndhpubKey: %s", dumpHexData(dh_pubKey).c_str()); + + uint8_t algo = 0x9b; + uint8_t keyId = CIE_KEY_DH_ID; + ByteArray algoBa = VarToByteArray(algo); + ByteArray keyIdBa = VarToByteArray(keyId); + + d1.setASN1Tag(0x80, algoBa).append(ASN1Tag(0x83, keyIdBa)).append(ASN1Tag(0x91, dh_pubKey)); + + uint8_t MSE_SET[] = { 0x00, 0x22, 0x41, 0xa6 }; + StatusWord sw; + if ((sw = SendAPDU(VarToByteArray(MSE_SET), d1, resp)) != 0x9000) + throw scard_error(sw); + uint8_t GET_DATA[] = { 0x00, 0xcb, 0x3f, 0xff }; + uint8_t GET_DATA_Data[] = { 0x4d, 0x04, 0xa6, 0x02, 0x91, 0x00 }; + if ((sw = SendAPDU(VarToByteArray(GET_DATA), VarToByteArray(GET_DATA_Data), resp)) != 0x9000) + throw scard_error(sw); + + asn1.Parse(resp); + dh_ICCpubKey = asn1.tags[0]->tags[0]->content; + +// printf("\ndhICCpubKey: %s", dumpHexData(dh_ICCpubKey).c_str()); + + secret = rsa.RSA_PURE(dh_ICCpubKey); + +// printf("\nsecret: %s", dumpHexData(secret).c_str()); + + CSHA256 sha256; + + uint8_t diffENC[] = { 0x00, 0x00, 0x00, 0x01 }; + uint8_t diffMAC[] = { 0x00, 0x00, 0x00, 0x02 }; + + sessENC = sha256.Digest(ByteDynArray(secret).append(VarToByteArray(diffENC))).left(16); + sessMAC = sha256.Digest(ByteDynArray(secret).append(VarToByteArray(diffMAC))).left(16); + +// printf("\nsessENC: %s", dumpHexData(sessENC).c_str()); +// printf("\nsessMAC: %s\n", dumpHexData(sessMAC).c_str()); + + sessSSC.resize(8); + sessSSC.fill(0); + sessSSC[7] = 1; + + ActiveSM = true; + exit_func +} + +void IAS::increment(ByteArray &seq) { + for (size_t i = seq.size() - 1; i >= 0; i--) { + if (seq[i] < 255) { + seq[i]++; + for (size_t j = i + 1; j < seq.size(); j++) + seq[j] = 0; + return; + } + } +} + + +ByteDynArray IAS::SM(ByteArray &keyEnc, ByteArray &keySig, ByteArray &apdu, ByteArray &seq) { + init_func + + std::string dmp; + ODS(dumpHexData(seq, dmp).c_str()); + + increment(seq); + + ODS(dumpHexData(seq, dmp).c_str()); + + ByteDynArray smHead; + smHead = apdu.left(4); + smHead[0] |= 0x0C; +// printf("apdu: %s\n", dumpHexData(smHead).c_str()); + + auto calcMac = ISOPad(ByteDynArray(seq).append(smHead)); + +// printf("calcMac: %s\n", dumpHexData(calcMac).c_str()); + + ByteDynArray iv(8); + iv.fill(0); // IV for APDU encryption and signature should be 0. Please refer to IAS specification §7.1.9 Secure messaging – Command APDU protection + +// printf("iv: %s\n", dumpHexData(iv).c_str()); + +// printf("keyEnc: %s\n", dumpHexData(keyEnc).c_str()); + CDES3 encDes(keyEnc, iv); + +// printf("keySig: %s\n", dumpHexData(keySig).c_str()); + + CMAC sigMac(keySig, iv); + + uint8_t Val01 = 1; +// uint8_t Val00 = 0; + + ByteDynArray datafield, doob; + if (apdu[4] != 0 && apdu.size() > 5) { + + ByteDynArray enc = encDes.RawEncode(ISOPad(apdu.mid(5, apdu[4]))); + +// printf("enc 1: %s\n", dumpHexData(enc).c_str()); + + if ((apdu[1] & 1) == 0) + doob.setASN1Tag(0x87, VarToByteDynArray(Val01).append(enc)); + else + doob.setASN1Tag(0x85, enc); + + calcMac.append(doob); + datafield.append(doob); + +// printf("calcMac 1: %s\n", dumpHexData(calcMac).c_str()); +// printf("datafield 1: %s\n", dumpHexData(datafield).c_str()); + } + if (apdu[4] == 0 && apdu.size() > 7) { + + ByteDynArray enc = encDes.RawEncode(ISOPad(apdu.mid(7, (apdu[5] << 8)| apdu[6] ))); + if ((apdu[1] & 1) == 0) + doob.setASN1Tag(0x87, VarToByteDynArray(Val01).append(enc)); + else + doob.setASN1Tag(0x85, enc); + + calcMac.append(doob); + datafield.append(doob); + +// printf("calcMac 2: %s\n", dumpHexData(calcMac).c_str()); +// printf("datafield 2: %s\n", dumpHexData(datafield).c_str()); + } + if (apdu.size() == 5 || apdu.size() == (apdu[4] + 6)) { + uint8_t le = apdu[apdu.size() - 1]; + ByteArray leBa = VarToByteArray(le); + doob.setASN1Tag(0x97, leBa); + calcMac.append(doob); + datafield.append(doob); + +// printf("calcMac 3: %s\n", dumpHexData(calcMac).c_str()); +// printf("datafield 3: %s\n", dumpHexData(datafield).c_str()); + } + + ByteDynArray macBa = sigMac.Mac(ISOPad(calcMac)); +// printf("macBa: %s\n", dumpHexData(macBa).c_str()); + + ByteDynArray tagMacBa = ASN1Tag(0x8e, macBa); +// printf("tagMacBa: %s\n", dumpHexData(tagMacBa).c_str()); + datafield.append(tagMacBa); + +// printf("datafield 4: %s\n", dumpHexData(datafield).c_str()); + + ByteDynArray elabResp; + if (datafield.size()<0x100) + elabResp.set(&smHead, (uint8_t)datafield.size(), &datafield, (uint8_t)0x00); + else { + auto len = datafield.size(); + auto lenBA = VarToByteArray(len); + ByteArray lenBa = lenBA.reverse().right(3); + + elabResp.set(&smHead, &lenBa, &datafield, (uint8_t)0x00, (uint8_t)0x00); + } + +// printf("elabResp: %s\n", dumpHexData(elabResp).c_str()); + return elabResp; +} + +StatusWord IAS::respSM(ByteArray &keyEnc, ByteArray &keySig, ByteArray &resp, ByteArray &seq, ByteDynArray &elabResp) { + init_func + + increment(seq); + DWORD index, llen, lgn; + StatusWord sw = 0xffff; + ByteDynArray encData; + ByteDynArray respMac, calcMac; + ByteDynArray iv(8); + iv.fill(0); // IV for APDU encryption should be 0. Please refer to IAS specification §7.1.9 Secure messaging – Command APDU protection + CDES3 encDes(keyEnc, iv); + CMAC sigMac(keySig, iv); + + calcMac = seq; + index = 0; + do { + + if (resp[index] == 0x99) { + calcMac.append(resp.mid(index, resp[index + 1] + 2)); + sw = resp[index + 2] << 8 | resp[index + 3]; + index += 4; + } else if (resp[index] == 0x8e) { + if (resp[index + 1] != 0x08) + throw logged_error("Lunghezza del MAC non valida"); + respMac = resp.mid(index + 2, 8); + index += 10; + } else if (resp[index] == 0x85) { + if (resp[index + 1] > 0x80) { + llen = resp[index + 1] - 0x80; + if (llen == 1) + lgn = resp[index + 2]; + else if (llen == 2) + lgn = (resp[index + 2] << 8) | resp[index + 3]; + else + throw logged_error(stdPrintf("Lunghezza ASN1 non valida: %i", llen)); + encData = resp.mid(index + llen + 2, lgn); + calcMac.append(resp.mid(index, lgn + llen + 2)); + index += llen + lgn + 2; + } else { + encData = resp.mid(index + 2, resp[index + 1]); + calcMac.append(resp.mid(index, resp[index + 1] + 2)); + index += resp[index + 1] + 2; + } + } else if (resp[index] == 0x87) { + if (resp[index + 1] > 0x80) { + llen = resp[index + 1] - 0x80; + if (llen == 1) + lgn = resp[index + 2]; + else if (llen == 2) + lgn = (resp[index + 2] << 8) | resp[index + 3]; + else + throw logged_error(stdPrintf("Lunghezza ASN1 non valida: %i", llen)); + encData = resp.mid(index + llen + 3, lgn - 1); + calcMac.append(resp.mid(index, lgn + llen + 2)); + index += llen + lgn + 2; + } else { + encData = resp.mid(index + 3, resp[index + 1] - 1); + calcMac.append(resp.mid(index, resp[index + 1] + 2)); + index += resp[index + 1] + 2; + } + } else + throw logged_error("Tag non riconosciuto nella risposta in Secure Messaging"); + } while (index < resp.size()); + + + auto smMac = sigMac.Mac(ISOPad(calcMac)); + ER_ASSERT(smMac == respMac,"Errore nel checksum della risposta del chip") + + if (!encData.isEmpty()) { + + elabResp=encDes.RawDecode(encData); + elabResp.resize(RemoveISOPad(elabResp),true); + } else + elabResp.clear(); + + return sw; +} + +StatusWord IAS::getResp(ByteDynArray &resp, StatusWord sw,ByteDynArray &elabresp) { + init_func + elabresp.clear(); + if (resp.size() != 0) + elabresp.append(resp); + + ByteDynArray curresp; + while (true) { + if ((sw >> 8) == 0x61) { + uint8_t ln = sw & 0xff; + if (ln != 0) { + uint8_t apdu[] = { 0x00, 0xc0, 0x00, 0x00, ln }; + sw = token.Transmit(VarToByteArray(apdu), &curresp); + elabresp.append(curresp); + return sw; + } else { + uint8_t apdu[] = { 0x00, 0xc0, 0x00, 0x00, 0x00 }; + sw = token.Transmit(VarToByteArray(apdu), &curresp); + elabresp.append(curresp); + } + } else { + return sw; + } + } + exit_func +} + +StatusWord IAS::getResp_SM(ByteArray &resp, StatusWord sw, ByteDynArray &elabresp) { + init_func + + + ByteDynArray s, ap; + CASNParser p; + elabresp.clear(); + if (resp.size() != 0) + elabresp.append(resp); + + ByteDynArray curresp; + while (true) { + if ((sw >> 8) == 0x61) { + uint8_t ln = sw & 0xff; + if (ln != 0) { + uint8_t apdu[] = { 0x00, 0xc0, 0x00, 0x00, ln }; + sw = token.Transmit(VarToByteArray(apdu), &curresp); + elabresp.append(curresp); + if (sw == 0x9000) + break; + if ((sw >> 8) != 0x61) + throw scard_error(sw); + } else { + uint8_t apdu[] = { 0x0c, 0xc0, 0x00, 0x00, 0x00 }; + sw = token.Transmit(VarToByteArray(apdu), &curresp); + elabresp.append(curresp); + } + } else if (sw == 0x9000 || sw == 0x6b00 || sw==0x6282) + break; + else + return sw; + } + return respSM(sessENC, sessMAC, elabresp, sessSSC, elabresp); + exit_func +} + + +StatusWord IAS::SendAPDU_SM(ByteArray head, ByteArray data, ByteDynArray &resp, uint8_t *le) { + init_func + ByteDynArray smApdu; + ByteDynArray s, curresp; + ByteArray emptyBa; + ByteArray leBa = VarToByteArray(*le); + std::string str; + + StatusWord sw; + if (data.size() < 0xE7) { + + smApdu.set(&head, (uint8_t)data.size(), &data, (le == nullptr) ? &emptyBa : &leBa); + + +// //Log.writePure("%s", std::string().append("\nClear APDU:").append(dumpHexData(smApdu, str)).append("\n").c_str()); + smApdu = SM(sessENC, sessMAC, smApdu, sessSSC); + +// //Log.writePure("%s", std::string().append("\nAPDU:").append(dumpHexData(smApdu)).append("\n").c_str()); + + sw = token.Transmit(smApdu, &curresp); + +// //Log.writePure("%s", std::string().append("RESP:").append(dumpHexData(curresp)).append("\n").c_str()); + + sw = getResp_SM(curresp, sw, resp); + + +// //Log.writePure("%s", std::string().append("Clear RESP:").append(dumpHexData(resp, str)).append(HexByte(sw >> 8)).append(HexByte(sw & 0xff)).append("\n").c_str()); + return sw; + } else { + // attenzione: + // in alcuni casi la carta ritorna 61xx fra un comando e l'altro in chaining. Questo è un grosso problema, perchè + // la get response sembra che faccia saltare il chaining. Forse è una questione di driver del lettore? + // Per daesso l'ho osservato solo su una virtual machine Win7 con il lettore in sharing con l'host + + +// size_t ds = data.size(); + size_t i = 0; + uint8_t cla = head[0]; + while (true) { + s = data.mid(i, min1(0xE7, data.size() - i)); + i += s.size(); + if (i != data.size()) + head[0] = cla | 0x10; + else + head[0] = cla; + if (s.size() != 0) + smApdu.set(&head, (BYTE)s.size(), &s, (le == nullptr || i < data.size()) ? &emptyBa : &leBa); + else + smApdu.set(&head, (le == nullptr || i < data.size()) ? &emptyBa : &leBa); + +// //Log.writePure("%s", std::string("Clear APDU:").append(dumpHexData(smApdu, str)).append("\n").c_str()); + smApdu = SM(sessENC, sessMAC, smApdu, sessSSC); + +// //Log.writePure("%s", std::string().append("\nAPDU:").append(dumpHexData(smApdu)).append("\n").c_str()); + + sw = token.Transmit(smApdu, &curresp); + +// //Log.writePure("%s",std::string().append("\nRESP:").append(dumpHexData(curresp)).append("\n").c_str()); + + sw = getResp_SM(curresp, sw, resp); + +// //Log.writePure("%s", std::string("Clear RESP:").append(dumpHexData(resp, str)).append(HexByte(sw >> 8)).append(HexByte(sw & 0xff)).append("\n").c_str()); + if (i == data.size()) + return sw; + } + + } + exit_func +} + + +StatusWord IAS::SendAPDU(ByteArray head, ByteArray data, ByteDynArray &resp, uint8_t *le) { + init_func + + ByteArray emptyBa; + ByteArray leBa = VarToByteArray(*le); + std::string str; + + ByteDynArray apdu, curresp; + auto ds = data.size(); + + if (ds > 255) { + size_t i = 0; + uint8_t cla = head[0]; + while (true) { + auto s = data.mid(i, min1(data.size()-i,255)); + i += s.size(); + if (i != data.size()) + head[0] = (cla | 0x10); + else + head[0] = cla; + + apdu.set(&head, (BYTE)s.size(), &s, le == nullptr ? &emptyBa : &leBa); + + StatusWord sw=token.Transmit(apdu, &curresp); + if (i == data.size()) { + sw = getResp(curresp, sw, resp); + + return sw; + } + } + } else { + if (data.size()!=0) + apdu.set(&head, (BYTE)data.size(), &data, le == nullptr ? &emptyBa : &leBa); + else + apdu.set(&head, le == nullptr ? &emptyBa : &leBa); + +// //Log.writePure("%s", std::string().append("\nAPDU:").append(dumpHexData(apdu)).append("\n").c_str()); + + StatusWord sw = token.Transmit(apdu, &curresp); + +// //Log.writePure("%s",std::string().append("RESP:").append(dumpHexData(curresp)).append("\n").c_str()); + + sw=getResp(curresp, sw, resp); + + return sw; + } + exit_func +} + + +void IAS::InitDHParam() { + init_func + ByteDynArray resp; + + CASNParser parser; + StatusWord sw; + + if (type == CIE_Type::CIE_Gemalto) { + uint8_t getDHDoup[] = { 00, 0xcb, 0x3f, 0xff }; + uint8_t getDHDuopData[] = { 0x4d, 0x08, 0x70, 0x06, 0xBF, 0xA1, 0x01, 0x02, 0xA3, 0x80 }; + + if ((sw = SendAPDU(VarToByteArray(getDHDoup), VarToByteArray(getDHDuopData), resp)) != 0x9000) + throw scard_error(sw); + + parser.Parse(resp); + + dh_g = parser.tags[0]->tags[0]->tags[0]->tags[0]->content; + dh_p = parser.tags[0]->tags[0]->tags[0]->tags[1]->content; + dh_q = parser.tags[0]->tags[0]->tags[0]->tags[2]->content; + } else if (type == CIE_Type::CIE_NXP || type == CIE_Type::CIE_STM || type == CIE_Type::CIE_STM2 || type == CIE_Type::CIE_STM3) { + uint8_t getDHDoup[] = { 00, 0xcb, 0x3f, 0xff }; + uint8_t getDHDuopData_g[] = { 0x4D, 0x0A, 0x70, 0x08, 0xBF, 0xA1, 0x01, 0x04, 0xA3, 0x02, 0x97, 0x00 }; + + if ((sw = SendAPDU(VarToByteArray(getDHDoup), VarToByteArray(getDHDuopData_g), resp)) != 0x9000) + throw scard_error(sw); + parser.Parse(resp); + dh_g = parser.tags[0]->tags[0]->tags[0]->tags[0]->content; + + uint8_t getDHDuopData_p[] = { 0x4D, 0x0A, 0x70, 0x08, 0xBF, 0xA1, 0x01, 0x04, 0xA3, 0x02, 0x98, 0x00 }; + if ((sw = SendAPDU(VarToByteArray(getDHDoup), VarToByteArray(getDHDuopData_p), resp)) != 0x9000) + throw scard_error(sw); + parser.Parse(resp); + dh_p = parser.tags[0]->tags[0]->tags[0]->tags[0]->content; + + uint8_t getDHDuopData_q[] = { 0x4D, 0x0A, 0x70, 0x08, 0xBF, 0xA1, 0x01, 0x04, 0xA3, 0x02, 0x99, 0x00 }; + if ((sw = SendAPDU(VarToByteArray(getDHDoup), VarToByteArray(getDHDuopData_q), resp)) != 0x9000) + throw scard_error(sw); + parser.Parse(resp); + dh_q = parser.tags[0]->tags[0]->tags[0]->tags[0]->content; + } else + throw logged_error("CIE non riconosciuta"); + + + exit_func +} + +CASNTag *GetTag(CASNTagArray &tags, DWORD id) { + for (std::size_t i = 0; i < tags.size(); i++) { + if (tags[i]->tagInt() == id) + return tags[i].get(); + } + return nullptr; +} + +void IAS::InitExtAuthKeyParam() { + init_func + ByteDynArray resp; + + uint8_t getKeyDoup[] = { 00, 0xcb, 0x3f, 0xff }; + uint8_t getKeyDuopData[] = { 0x4d, 0x09, 0x70, 0x07, 0xBF, 0xA0, CIE_KEY_ExtAuth_ID & 0x7f, 0x03, 0x7F, 0x49, 0x80 }; + StatusWord sw; + if ((sw = SendAPDU(VarToByteArray(getKeyDoup), VarToByteArray(getKeyDuopData), resp)) != 0x9000) + throw scard_error(sw); + + CASNParser parser; + parser.Parse(resp); + + CA_module = GetTag(parser.tags[0]->tags[0]->tags[0]->tags,0x81)->content; + CA_pubexp = GetTag(parser.tags[0]->tags[0]->tags[0]->tags, 0x82)->content; + CA_privexp = baExtAuth_PrivExp; + CA_CHR = GetTag(parser.tags[0]->tags[0]->tags[0]->tags, 0x5F20)->content; + CA_CHA = GetTag(parser.tags[0]->tags[0]->tags[0]->tags, 0x5F4C)->content; + CA_CAR = CA_CHR.mid(4); + CA_AID = CA_CHA.left(6); +} + +void IAS::SetCardContext(void* pCardData) { + token.setTransmitCallbackData(pCardData); +} + +void IAS::Deauthenticate() { + init_func + token.Reset(true); +} + +extern uint8_t encMod[]; +extern uint8_t encPriv[]; +extern uint8_t encPub[]; + +void IAS::InitEncKey() { + // uso la chiave di intAuth per i servizi per decifrare il certificato + init_func + std::string strPAN; + dumpHexData(PAN.mid(5, 6), strPAN, false); + + uint8_t mseSet[] = { 0x00, 0x22, 0x41, 0xa4 }; + uint8_t mseSetData[] = { 0x80, 0x01, 0x02, 0x84, 0x01, 0x83 }; + ByteDynArray resp; + StatusWord sw; + if (sessSSC.isEmpty()) { + if ((sw = SendAPDU(VarToByteArray(mseSet), VarToByteArray(mseSetData), resp)) != 0x9000) { + LOG_DEBUG("IAS::InitEncKey - sendapdu1 error: %x", sw); + throw scard_error(sw); + } + uint8_t intAuth[] = { 0x00, 0x88, 0x00, 0x00 }; + if ((sw = SendAPDU(VarToByteArray(intAuth), ByteArray((BYTE*)strPAN.c_str(), strPAN.length()), resp)) != 0x9000) { + LOG_DEBUG("IAS::InitEncKey - sendapdu2 error: %x", sw); + throw scard_error(sw); + } + } else { + if ((sw = SendAPDU_SM(VarToByteArray(mseSet), VarToByteArray(mseSetData), resp)) != 0x9000) { + LOG_DEBUG("IAS::InitEncKey - sendapdu3 error: %x", sw); + throw scard_error(sw); + } + uint8_t intAuth[] = { 0x00, 0x88, 0x00, 0x00 }; + if ((sw = SendAPDU_SM(VarToByteArray(intAuth), ByteArray((BYTE*)strPAN.c_str(), strPAN.length()), resp)) != 0x9000) { + LOG_DEBUG("IAS::InitEncKey - sendapdu4 error: %x", sw); + throw scard_error(sw); + } + } + + CSHA512 sha512; + auto cardSeed = sha512.Digest(resp); + CardEncKey = cardSeed.left(32); + CardEncIv= cardSeed.mid(32).left(16); +} + +void IAS::SetCache(const char *PAN, ByteArray &certificate, ByteArray &FirstPIN) { + init_func + ByteDynArray encCert, encPIN; + CAES enc(CardEncKey, CardEncIv); + + encCert=enc.Encode(certificate); + encPIN=enc.Encode(FirstPIN); + CacheSetData(PAN, encCert.data(), (int)encCert.size(), encPIN.data(), (int)encPIN.size()); +} + +int integrity = 0; +bool IsLowIntegrity() { + return + integrity == 1; +} + + +void IAS::IconaSbloccoPIN() { + init_func + +} + +void IAS::GetFirstPIN(ByteDynArray &PIN) { + init_func + std::string PANStr; + dumpHexData(PAN.mid(5, 6), PANStr, false); + std::vector EncPINBuf; + CacheGetPIN(PANStr.c_str(), EncPINBuf); + + CAES enc(CardEncKey, CardEncIv); + PIN = enc.Decode(ByteArray(EncPINBuf.data(), EncPINBuf.size())); +} + +bool IAS::IsEnrolled() { + init_func + std::string PANStr; + dumpHexData(PAN.mid(5, 6), PANStr, false); + return CacheExists(PANStr.c_str()); +} + +bool IAS::IsEnrolled(const char* szPAN) { + init_func + return CacheExists(szPAN); +} + + +bool IAS::Unenroll(const char* szPAN) { + init_func + return CacheRemove(szPAN); +} + +bool IAS::Unenroll() { + init_func + std::string PANStr; + dumpHexData(PAN.mid(5, 6), PANStr, false); + return CacheRemove(PANStr.c_str()); +} + +void IAS::GetCertificate(ByteDynArray &certificate,bool askEnable) { + init_func + if (!Certificate.isEmpty()) { + certificate = Certificate; + return; + } + + std::string PANStr; + dumpHexData(PAN.mid(5, 6), PANStr, false); + if (!CacheExists(PANStr.c_str())) { + + if (askEnable) { + + notifyCardNotRegistered(PANStr.c_str()); + //showUI(PANStr.c_str()); + + return; + } else { + certificate.clear(); + return; + } + } + + std::vector certEncBuf; + CacheGetCertificate(PANStr.c_str(), certEncBuf); + + CAES enc(CardEncKey, CardEncIv); + certificate = enc.Decode(ByteArray(certEncBuf.data(), certEncBuf.size())); + Certificate = certificate; +} + +uint8_t IAS::GetSODDigestAlg(ByteArray &SOD) { + CASNParser parser; + uint8_t OID_SHA512[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03 }; + uint8_t OID_SHA256[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 }; + + parser.Parse(SOD); + + std::string dump; + dumpHexData(SOD, dump); + + CASNTag &SODTag = *parser.tags[0]; + + CASNTag &temp = SODTag.Child(0, 0x30); + + CASNTag &temp2 = temp.Child(1, 0xA0).Child(0, 0x30); + + auto &digestAlgo = temp2.Child(1, 0x31).Child(0, 0x30).Child(0, 6).content; + + if (digestAlgo == VarToByteArray(OID_SHA256)) { + LOG_DEBUG("GetSODDigestAlg - SOD Digest Algo: SHA256"); + return 1; + } else if (digestAlgo == VarToByteArray(OID_SHA512)) { + LOG_DEBUG("GetSODDigestAlg - SOD Digest Algo: SHA512"); + return 2; + } else throw logged_error("GetSODDigestAlg - Digest algorithm not supported"); +} + +void IAS::VerificaSODPSS(ByteArray &SOD, std::map &hashSet) { + init_func + CASNParser parser; + parser.Parse(SOD); + + std::string dump; + dumpHexData(SOD, dump); + + CASNTag &SODTag = *parser.tags[0]; + + CASNTag &temp = SODTag.Child(0, 0x30); + + /* Verifica OID contentInfo */ + uint8_t OID[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02 }; + temp.Child(0, 06).Verify(VarToByteArray(OID)); + + uint8_t val3 = 3; + CASNTag &temp2 = temp.Child(1, 0xA0).Child(0, 0x30); + temp2.Child(0, 2).Verify(VarToByteArray(val3)); + + uint8_t OID_SHA512[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03 }; + temp2.Child(1, 0x31).Child(0, 0x30).Child(0, 6).Verify(VarToByteArray(OID_SHA512)); + + uint8_t OID3[] = { 0x67, 0x81, 0x08, 0x01, 0x01, 0x01 }; + temp2.Child(2, 0x30).Child(0, 06).Verify(VarToByteArray(OID3)); + + /* Prendo gli sha512 dei DG letti */ + ByteArray ttData = temp2.Child(2, 0x30).Child(1, 0xA0).Child(0, 04).content; + + CASNParser ttParser; + ttParser.Parse(ttData); + CASNTag &signedData = *ttParser.tags[0]; + signedData.CheckTag(0x30); + + /* Prendo il certificato del signer */ + CASNTag &signerCert = temp2.Child(3, 0xA0).Child(0, 0x30); + + CASNTag &temp3 = temp2.Child(4, 0x31).Child(0, 0x30); + uint8_t val1 = 1; + temp3.Child(0, 02).Verify(VarToByteArray(val1)); + + CASNTag &issuerName = temp3.Child(1, 0x30).Child(0, 0x30); + CASNTag &signerCertSerialNumber = temp3.Child(1, 0x30).Child(1, 02); + + temp3.Child(2, 0x30).Child(0, 06).Verify(VarToByteArray(OID_SHA512)); + + CASNTag &signerInfo = temp3.Child(3, 0xA0); + + uint8_t OID4[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x03 }; + signerInfo.Child(0, 0x30).Child(0, 06).Verify(VarToByteArray(OID4)); + + uint8_t OID5[] = { 0x67, 0x81, 0x08, 0x01, 0x01, 0x01 }; + signerInfo.Child(0, 0x30).Child(1, 0x31).Child(0, 06).Verify(VarToByteArray(OID5)); + + uint8_t OID6[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x04 }; + signerInfo.Child(1, 0x30).Child(0, 06).Verify(VarToByteArray(OID6)); + + CASNTag &digest = temp3.Child(3, 0xA0).Child(1, 0x30).Child(1, 0x31).Child(0, 04); + ByteArray digest_ = SOD.mid((int)digest.startPos, (int)(digest.endPos - digest.startPos)); + + uint8_t OID_RSAPSS[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0A }; + auto &signAlgo = temp3.Child(4, 0x30).Child(0, 06).content; + auto &digestAlgo = temp3.Child(4, 0x30).Child(1, 0x30).Child(0, 0xA0).Child(0, 0x30).Child(0, 06).content; + + if (digestAlgo != VarToByteArray(OID_SHA512)) + throw logged_error("VerificaSODPSS - Digest algorithm not valid"); + if(signAlgo != VarToByteArray(OID_RSAPSS)) + throw logged_error("VerificaSODPSS - Digest algorithm not valid"); + + CSHA512 sha512; + ByteArray toHash = ttData.mid((int)signedData.startPos, (int)(signedData.endPos - signedData.startPos)); + ByteDynArray calcDigest_ = sha512.Digest(toHash); + + if (calcDigest_ != digest.content) + throw logged_error("VerificaSODPSS - SOD Digest doesn't correspond to data"); + + CASNTag &signature = temp3.Child(5, 04); + + ByteArray certRaw = SOD.mid((int)signerCert.startPos, (int)(signerCert.endPos - signerCert.startPos)); + + CryptoPP::ByteQueue certin; + certin.Put(certRaw.data(),certRaw.size()); + CryptoPP::ByteQueue pbKey; + CryptoPP::ByteQueue issuer; + CryptoPP::Integer serial; + + GetPublicKeyFromCert(certin, pbKey, issuer, serial); + + ByteDynArray pubKeyData(pbKey.CurrentSize()); + pbKey.Get(pubKeyData.data(), pubKeyData.size()); + + CASNParser pubKeyParser; + pubKeyParser.Parse(pubKeyData); + CASNTag &pubKey = *pubKeyParser.tags[0]->tags[1]; + + ByteArray content = pubKey.content; + + if(content.data()[0] == 0) // unsigned bits + content = content.mid(1); + + CASNParser pubKeyParser2; + pubKeyParser2.Parse(content); + CASNTag &pubKey2 = *pubKeyParser2.tags[0]; + + CASNTag &modTag = pubKey2.Child(0, 02); + ByteArray mod = modTag.content; + while (mod[0] == 0) + mod = mod.mid(1); + CASNTag &expTag = pubKey2.Child(1, 02); + ByteArray exp = expTag.content; + while (exp[0] == 0) + exp = exp.mid(1); + + ByteArray signatureData = signature.content; + + CRSA rsa(mod, exp); + + ByteArray toSign = SOD.mid((int)signerInfo.tags[0]->startPos, (int)(signerInfo.tags[signerInfo.tags.size() - 1]->endPos - signerInfo.tags[0]->startPos)); + + ByteDynArray toSignBa = toSign.getASN1Tag(0x31); + ByteArray ba(toSignBa.data(), toSignBa.size()); + + bool result = rsa.RSA_PSS(signatureData, ba); + + if (!result) { + throw logged_error("VerificaSODPSS - SOD Sign not valid"); + } + + issuerName.Reparse(); + CASNParser issuerParser; + + ByteDynArray issuerBa(issuer.CurrentSize()); + issuer.Get(issuerBa.data(), issuerBa.size()); + + issuerParser.Parse(issuerBa); + + CASNTag &CertIssuer = *issuerParser.tags[0]; + if (issuerName.tags.size() != CertIssuer.tags.size()) +// throw logged_error("Issuer name non corrispondente"); + printf("Issuer name non corrispondente"); + + uint8_t val = 1; + signedData.Child(0, 02).Verify(VarToByteArray(val)); + signedData.Child(1, 0x30).Child(0, 06).Verify(VarToByteArray(OID_SHA512)); + + CASNTag &hashTag = signedData.Child(2, 0x30); + for (std::size_t i = 0; i &hashSet) { + init_func + CASNParser parser; + parser.Parse(SOD); + + std::string dump; + dumpHexData(SOD, dump); + + CASNTag &SODTag = *parser.tags[0]; + + CASNTag &temp = SODTag.Child(0, 0x30); + uint8_t OID[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02 }; + + temp.Child(0, 06).Verify(VarToByteArray(OID)); + uint8_t val3=3; + CASNTag &temp2 = temp.Child(1, 0xA0).Child(0, 0x30); + temp2.Child(0, 2).Verify(VarToByteArray(val3)); + + uint8_t OID_SH256[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 }; + temp2.Child(1, 0x31).Child(0, 0x30).Child(0, 6).Verify(VarToByteArray(OID_SH256)); + + uint8_t OID3[] = { 0x67, 0x81, 0x08, 0x01, 0x01, 0x01 }; + temp2.Child(2, 0x30).Child(0, 06).Verify(VarToByteArray(OID3)); + ByteArray ttData = temp2.Child(2, 0x30).Child(1, 0xA0).Child(0, 04).content; + CASNParser ttParser; + ttParser.Parse(ttData); + CASNTag &signedData = *ttParser.tags[0]; + signedData.CheckTag(0x30); + + CASNTag &signerCert = temp2.Child(3, 0xA0).Child(0, 0x30); + + CASNTag &temp3 = temp2.Child(4, 0x31).Child(0, 0x30); + uint8_t val1 = 1; + temp3.Child(0, 02).Verify(VarToByteArray(val1)); + CASNTag &issuerName = temp3.Child(1, 0x30).Child(0, 0x30); +// CASNTag &signerCertSerialNumber = temp3.Child(1, 0x30).Child(1, 02); + temp3.Child(2, 0x30).Child(0, 06).Verify(VarToByteArray(OID_SH256)); + + CASNTag &signerInfo = temp3.Child(3, 0xA0); + + uint8_t OID4[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x03 }; + signerInfo.Child(0, 0x30).Child(0, 06).Verify(VarToByteArray(OID4)); + uint8_t OID5[] = { 0x67, 0x81, 0x08, 0x01, 0x01, 0x01 }; + signerInfo.Child(0, 0x30).Child(1, 0x31).Child(0, 06).Verify(VarToByteArray(OID5)); + uint8_t OID6[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x04 }; + signerInfo.Child(1, 0x30).Child(0, 06).Verify(VarToByteArray(OID6)); + CASNTag &digest = temp3.Child(3, 0xA0).Child(1, 0x30).Child(1, 0x31).Child(0, 04); + + uint8_t OID_RSAwithSHA256[] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0b }; + uint8_t OID_RSAwithSHA1[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05 }; + auto &digestAlgo = temp3.Child(4, 0x30).Child(0, 06).content; + bool isSHA1 = false; + bool isSHA256 = false; + if (digestAlgo == VarToByteArray(OID_RSAwithSHA1)) + isSHA1 = true; + else if (digestAlgo == VarToByteArray(OID_RSAwithSHA256)) + isSHA256 = true; + else + throw logged_error("VerificaSOD - Digest algorithm not valid"); + + CASNTag &signature = temp3.Child(5, 04); + + ByteArray toHash = ttData.mid((int)signedData.startPos, (int)(signedData.endPos - signedData.startPos)); + CSHA256 sha256; + ByteDynArray calcDigest = sha256.Digest(toHash); + if (calcDigest!=digest.content) + throw logged_error("VerificaSOD - SOD digest does not match with data"); + + ByteArray certRaw = SOD.mid((int)signerCert.startPos, (int)(signerCert.endPos - signerCert.startPos)); + + + CryptoPP::ByteQueue certin; + certin.Put(certRaw.data(),certRaw.size()); + CryptoPP::ByteQueue pbKey; + CryptoPP::ByteQueue issuer; + CryptoPP::Integer serial; + + GetPublicKeyFromCert(certin, pbKey, issuer, serial); + +// long size = pbKey.CurrentSize(); +// BYTE* pbtPubKey = new BYTE[size]; +// pbKey.Get(pbtPubKey, size); +// +// ByteArray pubKeyData(pbtPubKey, pbKey.CurrentSize()); + + + + ByteDynArray pubKeyData(pbKey.CurrentSize()); + pbKey.Get(pubKeyData.data(), pubKeyData.size()); + + CASNParser pubKeyParser; + pubKeyParser.Parse(pubKeyData); + CASNTag &pubKey = *pubKeyParser.tags[0]->tags[1]; + + ByteArray content = pubKey.content; + + if(content.data()[0] == 0) // unsigned bits + content = content.mid(1); + + CASNParser pubKeyParser2; + pubKeyParser2.Parse(content); + CASNTag &pubKey2 = *pubKeyParser2.tags[0]; + + CASNTag &modTag = pubKey2.Child(0, 02); + ByteArray mod = modTag.content; + while (mod[0] == 0) + mod = mod.mid(1); + CASNTag &expTag = pubKey2.Child(1, 02); + ByteArray exp = expTag.content; + while (exp[0] == 0) + exp = exp.mid(1); + + ByteArray signatureData = signature.content; + + CRSA rsa(mod, exp); + + ByteDynArray decryptedSignature = rsa.RSA_PURE(signatureData); + decryptedSignature = decryptedSignature.mid(RemovePaddingBT1(decryptedSignature)); + + ByteArray toSign = SOD.mid((int)signerInfo.tags[0]->startPos, (int)(signerInfo.tags[signerInfo.tags.size()- 1]->endPos - signerInfo.tags[0]->startPos)); + + ByteDynArray digestSignature; + if (isSHA1) { + CSHA1 sha1; + decryptedSignature = decryptedSignature.mid(RemoveSha1(decryptedSignature)); + digestSignature = sha1.Digest(toSign.getASN1Tag(0x31)); + } + if (isSHA256) { + CSHA256 sha256; + decryptedSignature = decryptedSignature.mid(RemoveSha256(decryptedSignature)); + + ByteDynArray toSignBa = toSign.getASN1Tag(0x31); + ByteArray ba(toSignBa.data(), toSignBa.size()); + + digestSignature = sha256.Digest(ba); + + } + if (digestSignature!=decryptedSignature) + throw logged_error("VerificaSOD - SOD sign not valid"); +// throw logged_error("Firma del SOD non valida"); + + issuerName.Reparse(); + CASNParser issuerParser; + + ByteDynArray issuerBa(issuer.CurrentSize()); + issuer.Get(issuerBa.data(), issuerBa.size()); + + issuerParser.Parse(issuerBa); + + CASNTag &CertIssuer = *issuerParser.tags[0]; + if (issuerName.tags.size() != CertIssuer.tags.size()) +// throw logged_error("Issuer name non corrispondente"); + printf("Issuer name non corrispondente"); + + uint8_t val0=0; + signedData.Child(0, 02).Verify(VarToByteArray(val0)); + signedData.Child(1, 0x30).Child(0, 06).Verify(VarToByteArray(OID_SH256)); + + CASNTag &hashTag = signedData.Child(2, 0x30); + for (std::size_t i = 0; i #include +#include "../LOGGER/Logger.h" + +using namespace CieIDLogger; extern "C" { CK_RV CK_ENTRY CambioPIN(const char* szCurrentPIN, const char* szNuovoPIN, int* pAttempts, PROGRESS_CALLBACK progressCallBack); @@ -34,13 +37,13 @@ CK_RV CK_ENTRY CambioPIN(const char* szCurrentPIN, const char* szNewPIN, int* char* readers = NULL; char* ATR = NULL; + LOG_INFO("******** Starting PINManager::ChangePIN ********"); // verifica bontà PIN if(szCurrentPIN == NULL || strnlen(szCurrentPIN, 9) != 8) return CKR_PIN_LEN_RANGE; if(szNewPIN == NULL || strnlen(szNewPIN, 9) != 8) return CKR_PIN_LEN_RANGE; - try { DWORD len = 0; @@ -48,24 +51,35 @@ CK_RV CK_ENTRY CambioPIN(const char* szCurrentPIN, const char* szNewPIN, int* progressCallBack(10, "Connessione alla CIE"); + LOG_DEBUG("PINManager::ChangePIN - SCardEstablishContext"); long nRet = SCardEstablishContext(SCARD_SCOPE_USER, nullptr, nullptr, &hSC); - if(nRet != SCARD_S_SUCCESS) + if(nRet != SCARD_S_SUCCESS) { + LOG_ERROR("PINManager::ChangePIN - res: %d", nRet); return CKR_DEVICE_ERROR; + } - if (SCardListReaders(hSC, nullptr, NULL, &len) != SCARD_S_SUCCESS) { + LOG_DEBUG("PINManager::ChangePIN - SCardListReaders"); + + nRet = SCardListReaders(hSC, nullptr, NULL, &len); + if (nRet != SCARD_S_SUCCESS) { + LOG_ERROR("PINManager::ChangePIN - res: %d", nRet); return CKR_TOKEN_NOT_PRESENT; } - if(len == 1) + if(len == 1) { + LOG_ERROR("PINManager::ChangePIN - No readers"); return CKR_TOKEN_NOT_PRESENT; + } readers = (char*)malloc(len); - if (SCardListReaders(hSC, nullptr, (char*)readers, &len) != SCARD_S_SUCCESS) { + nRet = SCardListReaders(hSC, nullptr, (char*)readers, &len); + if (nRet != SCARD_S_SUCCESS) { free(readers); return CKR_TOKEN_NOT_PRESENT; } + LOG_INFO("PINManager::ChangePIN - CIE connected"); progressCallBack(10, "CIE Connessa"); char *curreader = readers; @@ -77,14 +91,18 @@ CK_RV CK_ENTRY CambioPIN(const char* szCurrentPIN, const char* szNewPIN, int* continue; DWORD atrLen = 40; - if(SCardGetAttrib(conn.hCard, SCARD_ATTR_ATR_STRING, (uint8_t*)ATR, &atrLen) != SCARD_S_SUCCESS) { + nRet = SCardGetAttrib(conn.hCard, SCARD_ATTR_ATR_STRING, (uint8_t*)ATR, &atrLen); + if(nRet != SCARD_S_SUCCESS) { + LOG_ERROR("PINManager::ChangePIN - SCardGetAttrib err: %d", nRet); free(readers); return CKR_DEVICE_ERROR; } ATR = (char*)malloc(atrLen); - if(SCardGetAttrib(conn.hCard, SCARD_ATTR_ATR_STRING, (uint8_t*)ATR, &atrLen) != SCARD_S_SUCCESS) { + nRet = SCardGetAttrib(conn.hCard, SCARD_ATTR_ATR_STRING, (uint8_t*)ATR, &atrLen); + if(nRet != SCARD_S_SUCCESS) { + LOG_ERROR("PINManager::ChangePIN - SCardGetAttrib err: %d", nRet); free(readers); free(ATR); return CKR_DEVICE_ERROR; @@ -127,26 +145,30 @@ CK_RV CK_ENTRY CambioPIN(const char* szCurrentPIN, const char* szNewPIN, int* ByteArray oldPINBa((BYTE*)szCurrentPIN, strlen(szCurrentPIN)); StatusWord sw = ias.VerifyPIN(oldPINBa); - - free(readers); - readers = NULL; - free(ATR); - ATR = NULL; + LOG_INFO("PINManager::VerifyPIN verify PIN status: %02X", sw); if (sw == 0x6983) { + free(readers); + free(ATR); return CKR_PIN_LOCKED; } if (sw >= 0x63C0 && sw <= 0x63CF) { if (pAttempts!=nullptr) *pAttempts = sw - 0x63C0; + free(readers); + free(ATR); return CKR_PIN_INCORRECT; } if (sw == 0x6700) { + free(readers); + free(ATR); return CKR_PIN_INCORRECT; } if (sw == 0x6300) { + free(readers); + free(ATR); return CKR_PIN_INCORRECT; } if (sw != 0x9000) { @@ -163,6 +185,7 @@ CK_RV CK_ENTRY CambioPIN(const char* szCurrentPIN, const char* szNewPIN, int* ByteArray newPINBa((BYTE*)szNewPIN, strlen(szNewPIN)); sw = ias.ChangePIN(oldPINBa, newPINBa); + LOG_INFO("PINManager::ChangePIN change PIN status: %02X", sw); if (sw != 0x9000) { throw scard_error(sw); } @@ -175,9 +198,12 @@ CK_RV CK_ENTRY CambioPIN(const char* szCurrentPIN, const char* szNewPIN, int* } progressCallBack(100, "Cambio PIN eseguito"); + LOG_INFO("******** PINManager::ChangePIN Completed ********"); } if (!foundCIE) { + free(readers); + free(ATR); return CKR_TOKEN_NOT_RECOGNIZED; } @@ -201,14 +227,13 @@ CK_RV CK_ENTRY CambioPIN(const char* szCurrentPIN, const char* szNewPIN, int* CK_RV CK_ENTRY SbloccoPIN(const char* szPUK, const char* szNewPIN, int* pAttempts, PROGRESS_CALLBACK progressCallBack) { char* readers = NULL; char* ATR = NULL; - + LOG_INFO("******** Starting PINManager::SbloccoPIN ********"); // verifica bontà PIN if(szPUK == NULL || strnlen(szPUK, 9) != 8) return CKR_PIN_LEN_RANGE; if(szNewPIN == NULL || strnlen(szNewPIN, 9) != 8) return CKR_PIN_LEN_RANGE; - try { DWORD len = 0; @@ -216,16 +241,22 @@ CK_RV CK_ENTRY SbloccoPIN(const char* szPUK, const char* szNewPIN, int* pAttem progressCallBack(10, "Connessione alla CIE"); + LOG_DEBUG("PINManager::UnlockPIN - SCardEstablishContext"); long nRet = SCardEstablishContext(SCARD_SCOPE_USER, nullptr, nullptr, &hSC); - if(nRet != SCARD_S_SUCCESS) + if(nRet != SCARD_S_SUCCESS) { + LOG_ERROR("PINManager::UnlockPIN - SCardEstablishContext err: %d", nRet); return CKR_DEVICE_ERROR; + } if (SCardListReaders(hSC, nullptr, NULL, &len) != SCARD_S_SUCCESS) { + LOG_ERROR("PINManager::UnlockPIN - SCardEstablishContext err: %d", nRet); return CKR_TOKEN_NOT_PRESENT; } - if(len == 1) + if(len == 1) { + LOG_ERROR("PINManager::UnlockPIN - No readers"); return CKR_TOKEN_NOT_PRESENT; + } readers = (char*)malloc(len); @@ -234,6 +265,7 @@ CK_RV CK_ENTRY SbloccoPIN(const char* szPUK, const char* szNewPIN, int* pAttem return CKR_TOKEN_NOT_PRESENT; } + LOG_INFO("PINManager::UnlockPIN - CIE connected"); progressCallBack(20, "CIE Connessa"); char *curreader = readers; @@ -246,6 +278,7 @@ CK_RV CK_ENTRY SbloccoPIN(const char* szPUK, const char* szNewPIN, int* pAttem DWORD atrLen = 40; if(SCardGetAttrib(conn.hCard, SCARD_ATTR_ATR_STRING, (uint8_t*)ATR, &atrLen) != SCARD_S_SUCCESS) { + LOG_ERROR("PINManager::UnlockPIN - SCardGetAttrib err: nRet"); free(readers); return CKR_DEVICE_ERROR; } @@ -295,6 +328,7 @@ CK_RV CK_ENTRY SbloccoPIN(const char* szPUK, const char* szNewPIN, int* pAttem ByteArray pukBa((BYTE*)szPUK, strlen(szPUK)); StatusWord sw = ias.VerifyPUK(pukBa); + LOG_INFO("PINManager::UnlockPIN VerifyPUK status: %02X", sw); if (sw == 0x6983) { free(ATR); @@ -335,6 +369,7 @@ CK_RV CK_ENTRY SbloccoPIN(const char* szPUK, const char* szNewPIN, int* pAttem ByteArray newPINBa((BYTE*)szNewPIN, strlen(szNewPIN)); sw = ias.ChangePIN(newPINBa); + LOG_INFO("PINManager::UnlockPIN ChangePIN status: %02X", sw); if (sw != 0x9000) { throw scard_error(sw); } @@ -347,6 +382,7 @@ CK_RV CK_ENTRY SbloccoPIN(const char* szPUK, const char* szNewPIN, int* pAttem } progressCallBack(100, "Sblocco carta eseguito"); + LOG_INFO("******** PINManager::UnlockPIN Completed ********"); } if (!foundCIE) { @@ -354,6 +390,8 @@ CK_RV CK_ENTRY SbloccoPIN(const char* szPUK, const char* szNewPIN, int* pAttem free(readers); return CKR_TOKEN_NOT_RECOGNIZED; } + + LOG_INFO("******** PINManager::SbloccoPIN Completed ********"); } catch(...) { if(ATR) free(ATR); diff --git a/libcie-pkcs11/CSP/VerificaConCIE.cpp b/libcie-pkcs11/CSP/VerificaConCIE.cpp index d5d08be1..0fba8963 100644 --- a/libcie-pkcs11/CSP/VerificaConCIE.cpp +++ b/libcie-pkcs11/CSP/VerificaConCIE.cpp @@ -8,6 +8,9 @@ #include "VerificaConCIE.h" #include "../PKCS11/PKCS11Functions.h" +#include "../LOGGER/Logger.h" + +using namespace CieIDLogger; VERIFY_RESULT verifyResult; @@ -27,7 +30,7 @@ CK_RV CK_ENTRY verificaConCIE( const char* inFilePath, const char* proxyAddress, if (verifyResult.nErrorCode == 0) { return 0; } else { - printf("Errore nella verifica: %lu\n", verifyResult.nErrorCode); + LOG_ERROR("verificaConCIE - Errore nella verifica: %lu\n", verifyResult.nErrorCode); return verifyResult.nErrorCode; } } diff --git a/libcie-pkcs11/Crypto/AES.cpp b/libcie-pkcs11/Crypto/AES.cpp index 05f5e3c1..6f76ce46 100644 --- a/libcie-pkcs11/Crypto/AES.cpp +++ b/libcie-pkcs11/Crypto/AES.cpp @@ -1,119 +1,119 @@ - -#include "AES.h" - -extern CLog Log; - -#ifdef WIN32 - -class init_aes { - public: - BCRYPT_ALG_HANDLE algo; - init_aes() { - if (BCryptOpenAlgorithmProvider(&algo, BCRYPT_AES_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0) != 0) - throw logged_error("Errore nell'inizializzazione dell'algoritmo AES"); - } - ~init_aes() { - BCryptCloseAlgorithmProvider(algo, 0); - } -} algo_aes; - -void CAES::Init(const ByteArray &key, const ByteArray &iv) { - init_func - ER_ASSERT(iv.size() == 16, "Errore nella lunghezza dell'Initial Vector") - this->iv = iv; - NTSTATUS ris; - if ((ris=BCryptGenerateSymmetricKey(algo_aes.algo, &this->key, nullptr, 0, key.data(), (ULONG)key.size(), 0)) != 0) - throw logged_error(stdPrintf("Errore nella creazione della chiave AES: %i %08x %08x", key.size(), algo_aes.algo, ris).c_str()); - - exit_func -} - -CAES::CAES() : key(nullptr) { -} - -CAES::~CAES(void) { - if (key!=nullptr) - BCryptDestroyKey(key); -} - -ByteDynArray CAES::AES(const ByteArray &data,int encOp) { - init_func - - ByteDynArray iv2 = iv; - size_t AppSize = data.size() - 1; - ByteDynArray resp(AppSize - (AppSize % 16) + 16); - - NTSTATUS rs; - ULONG result = (ULONG)resp.size(); - if (encOp == AES_ENCRYPT) - rs = BCryptEncrypt(key, data.data(), (ULONG)data.size(), nullptr, iv2.data(), (ULONG)iv2.size(), resp.data(), (ULONG)resp.size(), &result, 0); - - if (encOp == AES_DECRYPT) - rs = BCryptDecrypt(key, data.data(), (ULONG)data.size(), nullptr, iv2.data(), (ULONG)iv2.size(), resp.data(), (ULONG)resp.size(), &result, 0); - - if (rs != 0) - throw logged_error("Errore nella cifratura AES"); - - return resp; -} -#else - -ByteDynArray CAES::AES(const ByteArray &data,int encOp) { - init_func - - ByteDynArray iv2 = iv; - - AES_KEY aesKey; - if (encOp == AES_ENCRYPT) - AES_set_encrypt_key(key.data(), (int)key.size() * 8, &aesKey); - else - AES_set_decrypt_key(key.data(), (int)key.size() * 8, &aesKey); - size_t AppSize = data.size() - 1; - ByteDynArray resp(AppSize - (AppSize % 16) + 16); - AES_cbc_encrypt(data.data(), resp.data(), data.size(), &aesKey, iv2.data(), encOp); - - return resp; -} -void CAES::Init(const ByteArray &key, const ByteArray &iv) { - init_func - this->iv = iv; - this->key = key; - - exit_func -} - -CAES::CAES() { -} - -CAES::~CAES(void) { -} -#endif - -CAES::CAES(const ByteArray &key, const ByteArray &iv) { - Init(key, iv); -} - - -ByteDynArray CAES::Encode(const ByteArray &data) { - init_func - return AES(ISOPad16(data), AES_ENCRYPT); -} - -ByteDynArray CAES::RawEncode(const ByteArray &data) { - init_func - ER_ASSERT((data.size() % AES_BLOCK_SIZE) == 0, "La dimensione dei dati da cifrare deve essere multipla di 16"); - return AES(data, AES_ENCRYPT); -} - -ByteDynArray CAES::Decode(const ByteArray &data) { - init_func - ByteDynArray result=AES(data, AES_DECRYPT); - result.resize(RemoveISOPad(result),true); - return result; -} - -ByteDynArray CAES::RawDecode(const ByteArray &data) { - init_func - ER_ASSERT((data.size() % AES_BLOCK_SIZE) == 0, "La dimensione dei dati da cifrare deve essere multipla di 16"); - return AES(data, AES_DECRYPT); -} + +#include "AES.h" + +extern CLog Log; + +#ifdef WIN32 + +class init_aes { + public: + BCRYPT_ALG_HANDLE algo; + init_aes() { + if (BCryptOpenAlgorithmProvider(&algo, BCRYPT_AES_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0) != 0) + throw logged_error("Errore nell'inizializzazione dell'algoritmo AES"); + } + ~init_aes() { + BCryptCloseAlgorithmProvider(algo, 0); + } +} algo_aes; + +void CAES::Init(const ByteArray &key, const ByteArray &iv) { + init_func + ER_ASSERT(iv.size() == 16, "Errore nella lunghezza dell'Initial Vector") + this->iv = iv; + NTSTATUS ris; + if ((ris=BCryptGenerateSymmetricKey(algo_aes.algo, &this->key, nullptr, 0, key.data(), (ULONG)key.size(), 0)) != 0) + throw logged_error(stdPrintf("Errore nella creazione della chiave AES: %i %08x %08x", key.size(), algo_aes.algo, ris).c_str()); + + exit_func +} + +CAES::CAES() : key(nullptr) { +} + +CAES::~CAES(void) { + if (key!=nullptr) + BCryptDestroyKey(key); +} + +ByteDynArray CAES::AES(const ByteArray &data,int encOp) { + init_func + + ByteDynArray iv2 = iv; + size_t AppSize = data.size() - 1; + ByteDynArray resp(AppSize - (AppSize % 16) + 16); + + NTSTATUS rs; + ULONG result = (ULONG)resp.size(); + if (encOp == AES_ENCRYPT) + rs = BCryptEncrypt(key, data.data(), (ULONG)data.size(), nullptr, iv2.data(), (ULONG)iv2.size(), resp.data(), (ULONG)resp.size(), &result, 0); + + if (encOp == AES_DECRYPT) + rs = BCryptDecrypt(key, data.data(), (ULONG)data.size(), nullptr, iv2.data(), (ULONG)iv2.size(), resp.data(), (ULONG)resp.size(), &result, 0); + + if (rs != 0) + throw logged_error("Errore nella cifratura AES"); + + return resp; +} +#else + +ByteDynArray CAES::AES(const ByteArray &data,int encOp) { + init_func + + ByteDynArray iv2 = iv; + + AES_KEY aesKey; + if (encOp == AES_ENCRYPT) + AES_set_encrypt_key(key.data(), (int)key.size() * 8, &aesKey); + else + AES_set_decrypt_key(key.data(), (int)key.size() * 8, &aesKey); + size_t AppSize = data.size() - 1; + ByteDynArray resp(AppSize - (AppSize % 16) + 16); + AES_cbc_encrypt(data.data(), resp.data(), data.size(), &aesKey, iv2.data(), encOp); + + return resp; +} +void CAES::Init(const ByteArray &key, const ByteArray &iv) { + init_func + this->iv = iv; + this->key = key; + + exit_func +} + +CAES::CAES() { +} + +CAES::~CAES(void) { +} +#endif + +CAES::CAES(const ByteArray &key, const ByteArray &iv) { + Init(key, iv); +} + + +ByteDynArray CAES::Encode(const ByteArray &data) { + init_func + return AES(ISOPad16(data), AES_ENCRYPT); +} + +ByteDynArray CAES::RawEncode(const ByteArray &data) { + init_func + ER_ASSERT((data.size() % AES_BLOCK_SIZE) == 0, "La dimensione dei dati da cifrare deve essere multipla di 16"); + return AES(data, AES_ENCRYPT); +} + +ByteDynArray CAES::Decode(const ByteArray &data) { + init_func + ByteDynArray result=AES(data, AES_DECRYPT); + result.resize(RemoveISOPad(result),true); + return result; +} + +ByteDynArray CAES::RawDecode(const ByteArray &data) { + init_func + ER_ASSERT((data.size() % AES_BLOCK_SIZE) == 0, "La dimensione dei dati da cifrare deve essere multipla di 16"); + return AES(data, AES_DECRYPT); +} diff --git a/libcie-pkcs11/Crypto/ASNParser.cpp b/libcie-pkcs11/Crypto/ASNParser.cpp index bc36787d..f1889ed7 100644 --- a/libcie-pkcs11/Crypto/ASNParser.cpp +++ b/libcie-pkcs11/Crypto/ASNParser.cpp @@ -1,239 +1,239 @@ - -#include "../Util/Array.h" -#include "ASNParser.h" - -extern CLog Log; - -#define BitValue(a,b) ((a>>b) & 1) - -size_t GetASN1DataLenght(ByteArray &data) { - size_t l = 1; - uint8_t *cur = data.data(); - - size_t len = 0; - uint8_t curv = cur[0]; - - if ((curv & 0x1f) == 0x1f) { - while (true) { - l++; - cur++; - if (l >= data.size()) - throw logged_error("lunghezza eccessiva nell'ASN1"); - curv = cur[0]; - if ((curv & 0x80) != 0x80) - break; - } - } - - size_t llen = 0; - if (cur[1] == 0x80) { - llen = 1; - len = data.size() - l - 2; - } else if (BitValue(cur[1], 7) == 1) { - llen = (cur[1] & 0x7f); - for (size_t k = 0; k < llen; k++) { - len <<= 8; - len |= cur[k + 2]; - } - llen++; - } else { - llen = 1; - len = cur[1]; - } - return l + llen + len; -} -bool CASNTag::isSequence() { - return forcedSequence || ((tag.size()>=1) && (tag[0] & 0x20) == 0x20); -} - - -size_t CASNTag::ContentLen() { - if (!isSequence()) - return content.size(); - else { - size_t len = 0; - for (CASNTagArray::iterator i = tags.begin(); i != tags.end(); i++) - len += (*i)->EncodeLen(); - return len; - } -} - -size_t CASNTag::tagInt() { - size_t intVal = 0; - for (std::size_t i = 0; i < tag.size(); i++) { - intVal = (intVal << 8) | tag[i]; - } - return intVal; -} - -void CASNTag::Reparse() { - CASNParser parser; - //se è una bit string salto il numero di bit non usati - //attenzione in encode! non memorizzo il numero di bit non usati, quindi non posso - //ricostruirl'array originale! quindi lancio un'eccezione - if (tag.size()==1 && tag[0]==3) { - ByteArray input(content.mid(1)); - parser.Parse(input); - } else - parser.Parse(content); - if (parser.tags.size() > 0) { - forcedSequence = true; - for (auto t=parser.tags.begin(); t!=parser.tags.end(); t++) - tags.emplace_back(std::move(*t)); - parser.tags.clear(); - content.clear(); - } -} - -size_t CASNTag::EncodeLen() { - size_t tlen = tag.size(); - size_t clen = ContentLen(); - size_t llen = ASN1LLength(clen); - return tlen + llen + clen; -} - -void CASNTag::Encode(ByteArray &data, size_t &len) { - int tlen = (int)tag.size(); - if (tlen==1 && tag[0]==3 && forcedSequence) - throw logged_error("Bit string reparsed non gestite in encode!"); - data.copy(ByteArray(&tag[0], tlen)); - size_t clen = ContentLen(); - size_t llen = ASN1LLength(clen); - ByteArray input(data.mid(tlen)); - putASN1Length(clen, input); - - if (!isSequence()) { - data.mid(tlen + llen).copy(content); - len = tlen + llen + clen; - } else { - size_t ptrPos = tlen+llen; - for (CASNTagArray::iterator i = tags.begin(); i != tags.end(); i++) { - size_t taglen; - ByteArray input(data.mid(ptrPos)); - (*i)->Encode(input, taglen); - ptrPos += taglen; - } - len = ptrPos; - } -} - -CASNTag &CASNTag::Child(std::size_t num, uint8_t tag) { - if (num >= tags.size()) - throw logged_error("Errore nella verifica della struttura ASN1"); - if (tags[num]->tag.size() == 1 && tags[num]->tag[0]==tag) - return *tags[num]; - else - throw logged_error("Errore nella verifica del tag ASN1"); -} -CASNTag &CASNTag::CheckTag(uint8_t checkTag) { - if (tag.size() != 1 || tag[0] != checkTag) - throw logged_error("Errore nella verifica del tag ASN1"); - return *this; -} -void CASNTag::Verify(ByteArray checkContent) { - if (content!=checkContent) - throw logged_error("Errore nella verifica del tag ASN1"); -} - - -CASNTag::CASNTag(void) { - forcedSequence=false; - startPos = -1; - endPos = -1; -} - -CASNParser::CASNParser(void) { -} - -size_t CASNParser::CalcLen() { - size_t len=0; - for (CASNTagArray::iterator i = tags.begin(); i != tags.end(); i++) - len += (*i)->EncodeLen(); - return len; -} - -void CASNParser::Encode(ByteArray &data, CASNTagArray &tags) { - size_t ptrPos = 0; - for (CASNTagArray::iterator i = tags.begin(); i != tags.end(); i++) { - size_t len; - ByteArray input(data.mid(ptrPos)); - (*i)->Encode(input, len); - ptrPos += len; - } -} - -void CASNParser::Encode(ByteDynArray &data) { - size_t reqSize = CalcLen(); - data.resize(reqSize); - Encode(data, tags); -} - -void CASNParser::Parse(ByteArray &data) { - init_func - tags.clear(); - Parse(data,tags,0); -} - -void CASNParser::Parse(ByteArray &data, CASNTagArray &tags, size_t startseq) { - init_func - size_t l=0; - uint8_t *cur = data.data(); - while (l < data.size()) { - size_t len = 0; - - std::vector tagv; - uint8_t curv = cur[0]; - tagv.push_back(curv); - - if ((curv & 0x1f) == 0x1f) { - while (true) { - l++; - cur++; - if (l >= data.size()) - throw logged_error("lunghezza eccessiva nell'ASN1"); - curv = cur[0]; - tagv.push_back(curv); - if ((curv & 0x80) != 0x80) - // è l'ultimo byte del tag - break; - } - } - - int llen = 0; - if (cur[1] == 0x80) { - llen = 1; - len = data.size() - l - 2; - } else if (BitValue(cur[1], 7) == 1) { - llen = (cur[1] & 0x7f); - for (int k = 0; k < llen; k++) { - len <<= 8; - len |= cur[k + 2]; - } - llen++; - } else { - llen = 1; - len = cur[1]; - } - if (tagv.size() > 0 && tagv[0] == 0 && len == 0) { - return; - } - if (l + (len + llen + 1) > data.size()) - throw logged_error("lunghezza eccessiva nell'ASN1"); - - auto tag = std::unique_ptr(new CASNTag()); - tag->startPos = startseq + l; - tag->tag = tagv; - if (tag->isSequence()) { - ByteArray input(&cur[llen + 1], len); - Parse(input, tag->tags, startseq + l + llen + 1); - } else { - // è un valore singolo - tag->content = ByteArray(&cur[llen + 1], len); - } - l += len + llen + 1; - cur += len + llen + 1; - tag->endPos = tag->startPos + len + llen + 1; - tags.emplace_back(std::move(tag)); - } -} - + +#include "../Util/Array.h" +#include "ASNParser.h" + +extern CLog Log; + +#define BitValue(a,b) ((a>>b) & 1) + +size_t GetASN1DataLenght(ByteArray &data) { + size_t l = 1; + uint8_t *cur = data.data(); + + size_t len = 0; + uint8_t curv = cur[0]; + + if ((curv & 0x1f) == 0x1f) { + while (true) { + l++; + cur++; + if (l >= data.size()) + throw logged_error("lunghezza eccessiva nell'ASN1"); + curv = cur[0]; + if ((curv & 0x80) != 0x80) + break; + } + } + + size_t llen = 0; + if (cur[1] == 0x80) { + llen = 1; + len = data.size() - l - 2; + } else if (BitValue(cur[1], 7) == 1) { + llen = (cur[1] & 0x7f); + for (size_t k = 0; k < llen; k++) { + len <<= 8; + len |= cur[k + 2]; + } + llen++; + } else { + llen = 1; + len = cur[1]; + } + return l + llen + len; +} +bool CASNTag::isSequence() { + return forcedSequence || ((tag.size()>=1) && (tag[0] & 0x20) == 0x20); +} + + +size_t CASNTag::ContentLen() { + if (!isSequence()) + return content.size(); + else { + size_t len = 0; + for (CASNTagArray::iterator i = tags.begin(); i != tags.end(); i++) + len += (*i)->EncodeLen(); + return len; + } +} + +size_t CASNTag::tagInt() { + size_t intVal = 0; + for (std::size_t i = 0; i < tag.size(); i++) { + intVal = (intVal << 8) | tag[i]; + } + return intVal; +} + +void CASNTag::Reparse() { + CASNParser parser; + //se è una bit string salto il numero di bit non usati + //attenzione in encode! non memorizzo il numero di bit non usati, quindi non posso + //ricostruirl'array originale! quindi lancio un'eccezione + if (tag.size()==1 && tag[0]==3) { + ByteArray input(content.mid(1)); + parser.Parse(input); + } else + parser.Parse(content); + if (parser.tags.size() > 0) { + forcedSequence = true; + for (auto t=parser.tags.begin(); t!=parser.tags.end(); t++) + tags.emplace_back(std::move(*t)); + parser.tags.clear(); + content.clear(); + } +} + +size_t CASNTag::EncodeLen() { + size_t tlen = tag.size(); + size_t clen = ContentLen(); + size_t llen = ASN1LLength(clen); + return tlen + llen + clen; +} + +void CASNTag::Encode(ByteArray &data, size_t &len) { + int tlen = (int)tag.size(); + if (tlen==1 && tag[0]==3 && forcedSequence) + throw logged_error("Bit string reparsed non gestite in encode!"); + data.copy(ByteArray(&tag[0], tlen)); + size_t clen = ContentLen(); + size_t llen = ASN1LLength(clen); + ByteArray input(data.mid(tlen)); + putASN1Length(clen, input); + + if (!isSequence()) { + data.mid(tlen + llen).copy(content); + len = tlen + llen + clen; + } else { + size_t ptrPos = tlen+llen; + for (CASNTagArray::iterator i = tags.begin(); i != tags.end(); i++) { + size_t taglen; + ByteArray input(data.mid(ptrPos)); + (*i)->Encode(input, taglen); + ptrPos += taglen; + } + len = ptrPos; + } +} + +CASNTag &CASNTag::Child(std::size_t num, uint8_t tag) { + if (num >= tags.size()) + throw logged_error("Errore nella verifica della struttura ASN1"); + if (tags[num]->tag.size() == 1 && tags[num]->tag[0]==tag) + return *tags[num]; + else + throw logged_error("Errore nella verifica del tag ASN1"); +} +CASNTag &CASNTag::CheckTag(uint8_t checkTag) { + if (tag.size() != 1 || tag[0] != checkTag) + throw logged_error("Errore nella verifica del tag ASN1"); + return *this; +} +void CASNTag::Verify(ByteArray checkContent) { + if (content!=checkContent) + throw logged_error("Errore nella verifica del tag ASN1"); +} + + +CASNTag::CASNTag(void) { + forcedSequence=false; + startPos = -1; + endPos = -1; +} + +CASNParser::CASNParser(void) { +} + +size_t CASNParser::CalcLen() { + size_t len=0; + for (CASNTagArray::iterator i = tags.begin(); i != tags.end(); i++) + len += (*i)->EncodeLen(); + return len; +} + +void CASNParser::Encode(ByteArray &data, CASNTagArray &tags) { + size_t ptrPos = 0; + for (CASNTagArray::iterator i = tags.begin(); i != tags.end(); i++) { + size_t len; + ByteArray input(data.mid(ptrPos)); + (*i)->Encode(input, len); + ptrPos += len; + } +} + +void CASNParser::Encode(ByteDynArray &data) { + size_t reqSize = CalcLen(); + data.resize(reqSize); + Encode(data, tags); +} + +void CASNParser::Parse(ByteArray &data) { + init_func + tags.clear(); + Parse(data,tags,0); +} + +void CASNParser::Parse(ByteArray &data, CASNTagArray &tags, size_t startseq) { + init_func + size_t l=0; + uint8_t *cur = data.data(); + while (l < data.size()) { + size_t len = 0; + + std::vector tagv; + uint8_t curv = cur[0]; + tagv.push_back(curv); + + if ((curv & 0x1f) == 0x1f) { + while (true) { + l++; + cur++; + if (l >= data.size()) + throw logged_error("lunghezza eccessiva nell'ASN1"); + curv = cur[0]; + tagv.push_back(curv); + if ((curv & 0x80) != 0x80) + // è l'ultimo byte del tag + break; + } + } + + int llen = 0; + if (cur[1] == 0x80) { + llen = 1; + len = data.size() - l - 2; + } else if (BitValue(cur[1], 7) == 1) { + llen = (cur[1] & 0x7f); + for (int k = 0; k < llen; k++) { + len <<= 8; + len |= cur[k + 2]; + } + llen++; + } else { + llen = 1; + len = cur[1]; + } + if (tagv.size() > 0 && tagv[0] == 0 && len == 0) { + return; + } + if (l + (len + llen + 1) > data.size()) + throw logged_error("lunghezza eccessiva nell'ASN1"); + + auto tag = std::unique_ptr(new CASNTag()); + tag->startPos = startseq + l; + tag->tag = tagv; + if (tag->isSequence()) { + ByteArray input(&cur[llen + 1], len); + Parse(input, tag->tags, startseq + l + llen + 1); + } else { + // è un valore singolo + tag->content = ByteArray(&cur[llen + 1], len); + } + l += len + llen + 1; + cur += len + llen + 1; + tag->endPos = tag->startPos + len + llen + 1; + tags.emplace_back(std::move(tag)); + } +} + diff --git a/libcie-pkcs11/Crypto/DES3.cpp b/libcie-pkcs11/Crypto/DES3.cpp index 0278316e..02f2ce8a 100644 --- a/libcie-pkcs11/Crypto/DES3.cpp +++ b/libcie-pkcs11/Crypto/DES3.cpp @@ -1,166 +1,166 @@ - -#include "DES3.h" -#include - -extern CLog Log; - -#ifdef WIN32 -static char *szCompiledFile = __FILE__; -class init_3des { - public: - BCRYPT_ALG_HANDLE algo; - init_3des() { - if (BCryptOpenAlgorithmProvider(&algo, BCRYPT_3DES_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0) != 0) - throw logged_error("Errore nell'inizializzazione dell'algoritmo DES"); - } - ~init_3des() { - BCryptCloseAlgorithmProvider(algo, 0); - } -} algo_3des; - -void CDES3::Init(const ByteArray &key, const ByteArray &iv) { - init_func - size_t KeySize = key.size(); - ER_ASSERT((KeySize % 8) == 0, "Errore nella lunghezza della chiave DES (non divisibile per 8)") - ER_ASSERT(iv.size() == 8, "Errore nella lunghezza dell'Initial Vector") - ER_ASSERT(KeySize >= 8 && KeySize <= 24, "Errore nella lunghezza della chiave DES (<8 o >24)") - - ByteDynArray BCrytpKey; - this->iv = iv; - switch (KeySize) { - case 8: - BCrytpKey.set(&key, &key, &key); - break; - case 16: - BCrytpKey.set(&key, &key.left(8)); - break; - case 24: - BCrytpKey = key; - break; - } - - if (BCryptGenerateSymmetricKey(algo_3des.algo, &this->key, nullptr, 0, BCrytpKey.data(), (ULONG)BCrytpKey.size(), 0) != 0) - throw logged_error("Errore nella creazione della chiave DES"); - - exit_func -} - -CDES3::~CDES3(void) { - if (key!=nullptr) - BCryptDestroyKey(key); -} - -CDES3::CDES3(void) : key(nullptr) { -} - -ByteDynArray CDES3::Des3(const ByteArray &data, int encOp) { - init_func - - size_t AppSize = data.size() - 1; - ByteDynArray resp(AppSize - (AppSize % 8) + 8); - - NTSTATUS rs; - ByteDynArray iv2 = iv; - ULONG result = (ULONG)resp.size(); - if (encOp == DES_ENCRYPT) - rs = BCryptEncrypt(key, data.data(), (ULONG)data.size(), nullptr, iv2.data(), (ULONG)iv2.size(), resp.data(), (ULONG)resp.size(), &result, 0); - - if (encOp == DES_DECRYPT) - rs = BCryptDecrypt(key, data.data(), (ULONG)data.size(), nullptr, iv2.data(), (ULONG)iv2.size(), resp.data(), (ULONG)resp.size(), &result, 0); - - if (rs != 0) - throw logged_error("Errore nella cifratura DES"); - - return resp; -} - -#else - -void CDES3::Init(const ByteArray &key, const ByteArray &iv) { - init_func - long KeySize = key.size(); -// ER_ASSERT((KeySize % 8) == 0, "Errore nella lunghezza della chiave DES (non divisibile per 8)") -// ER_ASSERT(iv.size() == 8, "Errore nella lunghezza dell'Initial Vector") - -// ER_ASSERT(KeySize >= 8 && KeySize <= 24, "Errore nella lunghezza della chiave DES (<8 o >24)") - DES_cblock *keyVal1 = nullptr, *keyVal2 = nullptr, *keyVal3 = nullptr; - CryptoPP::memcpy_s(initVec, sizeof(DES_cblock), iv.data(), 8); - - switch (KeySize) { - case 8: - throw logged_error("Chiave 3DES 8 byte non supportata"); - //keyVal1 = keyVal2 = keyVal3 = (DES_cblock *)key.data(); - break; - case 16: - keyVal1 = keyVal3 = (DES_cblock *)key.left(8).data();//data(); - keyVal2 = (DES_cblock *)key.mid(8, 8).data(); - break; - case 24: - keyVal1 = (DES_cblock *)key.left(8).data(); - keyVal2 = (DES_cblock *)key.mid(8, 8).data(); - keyVal3 = (DES_cblock *)key.mid(16, 8).data(); - break; - } - - DES_set_key(keyVal1, &k1); - DES_set_key(keyVal2, &k2); - DES_set_key(keyVal3, &k3); - -// DES_set_key(keyVal1, k1); -// DES_set_key(keyVal2, k2); -// DES_set_key(keyVal3, k3); - - exit_func -} - -CDES3::~CDES3(void) { -} - -CDES3::CDES3() { -} - -ByteDynArray CDES3::Des3(const ByteArray &data, int encOp) { - init_func - - DES_cblock iv; - CryptoPP::memcpy_s(iv, sizeof(DES_cblock), initVec, sizeof(initVec)); - size_t AppSize = data.size() - 1; - ByteDynArray resp(AppSize - (AppSize % 8) + 8); - DES_ede3_cbc_encrypt(data.data(), resp.data(), (long)data.size(), &k1, &k2, &k3, &iv, encOp); - - return resp; -} -#endif - -CDES3::CDES3(const ByteArray &key, const ByteArray &iv) { - Init(key,iv); -} - -ByteDynArray CDES3::Encode(const ByteArray &data) { - init_func - return Des3(ISOPad(data), DES_ENCRYPT); -} - -ByteDynArray CDES3::RawEncode(const ByteArray &data) { - init_func - ByteDynArray result; - ER_ASSERT((data.size() % 8) == 0, "La dimensione dei dati da cifrare deve essere multipla di 8"); - - return Des3(data, DES_ENCRYPT); -} - -ByteDynArray CDES3::Decode(const ByteArray &data) { - init_func - auto result=Des3(data, DES_DECRYPT); - result.resize(RemoveISOPad(result), true); - return result; - -} - -ByteDynArray CDES3::RawDecode(const ByteArray &data) { - init_func - ByteDynArray result; - ER_ASSERT((data.size() % 8) == 0, "La dimensione dei dati da cifrare deve essere multipla di 8"); - - return Des3(data, DES_DECRYPT); -} + +#include "DES3.h" +#include + +extern CLog Log; + +#ifdef WIN32 +static char *szCompiledFile = __FILE__; +class init_3des { + public: + BCRYPT_ALG_HANDLE algo; + init_3des() { + if (BCryptOpenAlgorithmProvider(&algo, BCRYPT_3DES_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0) != 0) + throw logged_error("Errore nell'inizializzazione dell'algoritmo DES"); + } + ~init_3des() { + BCryptCloseAlgorithmProvider(algo, 0); + } +} algo_3des; + +void CDES3::Init(const ByteArray &key, const ByteArray &iv) { + init_func + size_t KeySize = key.size(); + ER_ASSERT((KeySize % 8) == 0, "Errore nella lunghezza della chiave DES (non divisibile per 8)") + ER_ASSERT(iv.size() == 8, "Errore nella lunghezza dell'Initial Vector") + ER_ASSERT(KeySize >= 8 && KeySize <= 24, "Errore nella lunghezza della chiave DES (<8 o >24)") + + ByteDynArray BCrytpKey; + this->iv = iv; + switch (KeySize) { + case 8: + BCrytpKey.set(&key, &key, &key); + break; + case 16: + BCrytpKey.set(&key, &key.left(8)); + break; + case 24: + BCrytpKey = key; + break; + } + + if (BCryptGenerateSymmetricKey(algo_3des.algo, &this->key, nullptr, 0, BCrytpKey.data(), (ULONG)BCrytpKey.size(), 0) != 0) + throw logged_error("Errore nella creazione della chiave DES"); + + exit_func +} + +CDES3::~CDES3(void) { + if (key!=nullptr) + BCryptDestroyKey(key); +} + +CDES3::CDES3(void) : key(nullptr) { +} + +ByteDynArray CDES3::Des3(const ByteArray &data, int encOp) { + init_func + + size_t AppSize = data.size() - 1; + ByteDynArray resp(AppSize - (AppSize % 8) + 8); + + NTSTATUS rs; + ByteDynArray iv2 = iv; + ULONG result = (ULONG)resp.size(); + if (encOp == DES_ENCRYPT) + rs = BCryptEncrypt(key, data.data(), (ULONG)data.size(), nullptr, iv2.data(), (ULONG)iv2.size(), resp.data(), (ULONG)resp.size(), &result, 0); + + if (encOp == DES_DECRYPT) + rs = BCryptDecrypt(key, data.data(), (ULONG)data.size(), nullptr, iv2.data(), (ULONG)iv2.size(), resp.data(), (ULONG)resp.size(), &result, 0); + + if (rs != 0) + throw logged_error("Errore nella cifratura DES"); + + return resp; +} + +#else + +void CDES3::Init(const ByteArray &key, const ByteArray &iv) { + init_func + long KeySize = key.size(); +// ER_ASSERT((KeySize % 8) == 0, "Errore nella lunghezza della chiave DES (non divisibile per 8)") +// ER_ASSERT(iv.size() == 8, "Errore nella lunghezza dell'Initial Vector") + +// ER_ASSERT(KeySize >= 8 && KeySize <= 24, "Errore nella lunghezza della chiave DES (<8 o >24)") + DES_cblock *keyVal1 = nullptr, *keyVal2 = nullptr, *keyVal3 = nullptr; + CryptoPP::memcpy_s(initVec, sizeof(DES_cblock), iv.data(), 8); + + switch (KeySize) { + case 8: + throw logged_error("Chiave 3DES 8 byte non supportata"); + //keyVal1 = keyVal2 = keyVal3 = (DES_cblock *)key.data(); + break; + case 16: + keyVal1 = keyVal3 = (DES_cblock *)key.left(8).data();//data(); + keyVal2 = (DES_cblock *)key.mid(8, 8).data(); + break; + case 24: + keyVal1 = (DES_cblock *)key.left(8).data(); + keyVal2 = (DES_cblock *)key.mid(8, 8).data(); + keyVal3 = (DES_cblock *)key.mid(16, 8).data(); + break; + } + + DES_set_key(keyVal1, &k1); + DES_set_key(keyVal2, &k2); + DES_set_key(keyVal3, &k3); + +// DES_set_key(keyVal1, k1); +// DES_set_key(keyVal2, k2); +// DES_set_key(keyVal3, k3); + + exit_func +} + +CDES3::~CDES3(void) { +} + +CDES3::CDES3() { +} + +ByteDynArray CDES3::Des3(const ByteArray &data, int encOp) { + init_func + + DES_cblock iv; + CryptoPP::memcpy_s(iv, sizeof(DES_cblock), initVec, sizeof(initVec)); + size_t AppSize = data.size() - 1; + ByteDynArray resp(AppSize - (AppSize % 8) + 8); + DES_ede3_cbc_encrypt(data.data(), resp.data(), (long)data.size(), &k1, &k2, &k3, &iv, encOp); + + return resp; +} +#endif + +CDES3::CDES3(const ByteArray &key, const ByteArray &iv) { + Init(key,iv); +} + +ByteDynArray CDES3::Encode(const ByteArray &data) { + init_func + return Des3(ISOPad(data), DES_ENCRYPT); +} + +ByteDynArray CDES3::RawEncode(const ByteArray &data) { + init_func + ByteDynArray result; + ER_ASSERT((data.size() % 8) == 0, "La dimensione dei dati da cifrare deve essere multipla di 8"); + + return Des3(data, DES_ENCRYPT); +} + +ByteDynArray CDES3::Decode(const ByteArray &data) { + init_func + auto result=Des3(data, DES_DECRYPT); + result.resize(RemoveISOPad(result), true); + return result; + +} + +ByteDynArray CDES3::RawDecode(const ByteArray &data) { + init_func + ByteDynArray result; + ER_ASSERT((data.size() % 8) == 0, "La dimensione dei dati da cifrare deve essere multipla di 8"); + + return Des3(data, DES_DECRYPT); +} diff --git a/libcie-pkcs11/Crypto/MAC.cpp b/libcie-pkcs11/Crypto/MAC.cpp index e135b971..596e58ae 100644 --- a/libcie-pkcs11/Crypto/MAC.cpp +++ b/libcie-pkcs11/Crypto/MAC.cpp @@ -1,135 +1,135 @@ - -#include "MAC.h" -#include - -extern CLog Log; - -#ifdef WIN32 - -static char *szCompiledFile=__FILE__; - -class init_mac { - public: - BCRYPT_ALG_HANDLE algo; - init_mac() { - if (BCryptOpenAlgorithmProvider(&algo, BCRYPT_3DES_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0) != 0) - throw logged_error("Errore nell'inizializzazione dell'algoritmo MAC"); - } - ~init_mac() { - BCryptCloseAlgorithmProvider(algo, 0); - } -} algo_mac; - -void CMAC::Init(const ByteArray &key, const ByteArray &iv) { - init_func - size_t KeySize = key.size(); - ER_ASSERT((KeySize % 8) == 0, "Errore nella lunghezza della chiave MAC (non divisibile per 8)") - ER_ASSERT(iv.size() == 8, "Errore nella lunghezza dell'Initial Vector") - ER_ASSERT(KeySize >= 8 && KeySize <= 24, "Errore nella lunghezza della chiave MAC (<8 o >24)") - ByteDynArray BCrytpKey; - this->iv = iv; - switch (KeySize) { - case 8: - - BCrytpKey.set(&key, &key, &key); - break; - case 16: - BCrytpKey.set(&key, &key.left(8)); - break; - case 24: - BCrytpKey = key; - break; - } - - ByteDynArray k1; - k1.set(&key.left(8), &key.left(8), &key.left(8)); - - if (BCryptGenerateSymmetricKey(algo_mac.algo, &this->key1, nullptr, 0, k1.data(), (ULONG)k1.size(), 0) != 0) - throw logged_error("Errore nella creazione della chiave MAC"); - - if (BCryptGenerateSymmetricKey(algo_mac.algo, &this->key2, nullptr, 0, BCrytpKey.data(), (ULONG)BCrytpKey.size(), 0) != 0) - throw logged_error("Errore nella creazione della chiave MAC"); - - exit_func -} - -CMAC::CMAC() : key1(nullptr), key2(nullptr) { -} - -CMAC::~CMAC(void) { - if (key1!=nullptr) - BCryptDestroyKey(key1); - if (key2 != nullptr) - BCryptDestroyKey(key2); -} - - -#else - -void CMAC::Init(const ByteArray &key, const ByteArray &iv) { - init_func - long KeySize = key.size(); -// ER_ASSERT((KeySize % 8) == 0, "Errore nella lunghezza della chiave MAC (non divisibile per 8)") -// ER_ASSERT(iv.size() == 8, "Errore nella lunghezza dell'Initial Vector") - -// ER_ASSERT(KeySize >= 8 && KeySize <= 24, "Errore nella lunghezza della chiave MAC (<8 o >24)") - DES_cblock *keyVal1 = nullptr, *keyVal2 = nullptr, *keyVal3 = nullptr; - CryptoPP::memcpy_s(initVec, sizeof(DES_cblock), iv.data(), 8); - - switch (KeySize) { - case 8: - throw logged_error("Errore nella cifratura DES"); - //keyVal1 = keyVal2 = keyVal3 = (DES_cblock *)key.data(); - break; - case 16: - keyVal1 = keyVal3 = (DES_cblock *)key.data(); - keyVal2 = (DES_cblock *)key.mid(8).data(); - break; - case 24: - keyVal1 = (DES_cblock *)key.data(); - keyVal2 = (DES_cblock *)key.mid(8).data(); - keyVal3 = (DES_cblock *)key.mid(16).data(); - break; - } - - DES_set_key(keyVal1, &k1); - DES_set_key(keyVal2, &k2); - DES_set_key(keyVal3, &k3); - - exit_func -} - -CMAC::~CMAC(void) { -} - -ByteDynArray CMAC::Mac(const ByteArray &data) { - init_func - - ByteDynArray resp(8); - - DES_cblock iv; - CryptoPP::memcpy_s(iv, sizeof(DES_cblock), initVec, sizeof(iv)); - - size_t ANSILen = ANSIPadLen(data.size()); - if (data.size()>8) { - ByteDynArray baOutTmp(ANSILen - 8); - DES_ncbc_encrypt(data.data(), baOutTmp.data(), (long)ANSILen - 8, &k1, &iv, DES_ENCRYPT); - } - uint8_t dest[8]; - DES_ede3_cbc_encrypt(data.mid(ANSILen - 8).data(), dest, (long)(data.size() - ANSILen) + 8, &k1, &k2, &k3, &iv, DES_ENCRYPT); - resp.copy(ByteArray(dest, 8)); - - return resp; - - exit_func -} - -CMAC::CMAC() { -} -#endif - - -CMAC::CMAC(const ByteArray &key, const ByteArray &iv) { - Init(key,iv); -} - + +#include "MAC.h" +#include + +extern CLog Log; + +#ifdef WIN32 + +static char *szCompiledFile=__FILE__; + +class init_mac { + public: + BCRYPT_ALG_HANDLE algo; + init_mac() { + if (BCryptOpenAlgorithmProvider(&algo, BCRYPT_3DES_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0) != 0) + throw logged_error("Errore nell'inizializzazione dell'algoritmo MAC"); + } + ~init_mac() { + BCryptCloseAlgorithmProvider(algo, 0); + } +} algo_mac; + +void CMAC::Init(const ByteArray &key, const ByteArray &iv) { + init_func + size_t KeySize = key.size(); + ER_ASSERT((KeySize % 8) == 0, "Errore nella lunghezza della chiave MAC (non divisibile per 8)") + ER_ASSERT(iv.size() == 8, "Errore nella lunghezza dell'Initial Vector") + ER_ASSERT(KeySize >= 8 && KeySize <= 24, "Errore nella lunghezza della chiave MAC (<8 o >24)") + ByteDynArray BCrytpKey; + this->iv = iv; + switch (KeySize) { + case 8: + + BCrytpKey.set(&key, &key, &key); + break; + case 16: + BCrytpKey.set(&key, &key.left(8)); + break; + case 24: + BCrytpKey = key; + break; + } + + ByteDynArray k1; + k1.set(&key.left(8), &key.left(8), &key.left(8)); + + if (BCryptGenerateSymmetricKey(algo_mac.algo, &this->key1, nullptr, 0, k1.data(), (ULONG)k1.size(), 0) != 0) + throw logged_error("Errore nella creazione della chiave MAC"); + + if (BCryptGenerateSymmetricKey(algo_mac.algo, &this->key2, nullptr, 0, BCrytpKey.data(), (ULONG)BCrytpKey.size(), 0) != 0) + throw logged_error("Errore nella creazione della chiave MAC"); + + exit_func +} + +CMAC::CMAC() : key1(nullptr), key2(nullptr) { +} + +CMAC::~CMAC(void) { + if (key1!=nullptr) + BCryptDestroyKey(key1); + if (key2 != nullptr) + BCryptDestroyKey(key2); +} + + +#else + +void CMAC::Init(const ByteArray &key, const ByteArray &iv) { + init_func + long KeySize = key.size(); +// ER_ASSERT((KeySize % 8) == 0, "Errore nella lunghezza della chiave MAC (non divisibile per 8)") +// ER_ASSERT(iv.size() == 8, "Errore nella lunghezza dell'Initial Vector") + +// ER_ASSERT(KeySize >= 8 && KeySize <= 24, "Errore nella lunghezza della chiave MAC (<8 o >24)") + DES_cblock *keyVal1 = nullptr, *keyVal2 = nullptr, *keyVal3 = nullptr; + CryptoPP::memcpy_s(initVec, sizeof(DES_cblock), iv.data(), 8); + + switch (KeySize) { + case 8: + throw logged_error("Errore nella cifratura DES"); + //keyVal1 = keyVal2 = keyVal3 = (DES_cblock *)key.data(); + break; + case 16: + keyVal1 = keyVal3 = (DES_cblock *)key.data(); + keyVal2 = (DES_cblock *)key.mid(8).data(); + break; + case 24: + keyVal1 = (DES_cblock *)key.data(); + keyVal2 = (DES_cblock *)key.mid(8).data(); + keyVal3 = (DES_cblock *)key.mid(16).data(); + break; + } + + DES_set_key(keyVal1, &k1); + DES_set_key(keyVal2, &k2); + DES_set_key(keyVal3, &k3); + + exit_func +} + +CMAC::~CMAC(void) { +} + +ByteDynArray CMAC::Mac(const ByteArray &data) { + init_func + + ByteDynArray resp(8); + + DES_cblock iv; + CryptoPP::memcpy_s(iv, sizeof(DES_cblock), initVec, sizeof(iv)); + + size_t ANSILen = ANSIPadLen(data.size()); + if (data.size()>8) { + ByteDynArray baOutTmp(ANSILen - 8); + DES_ncbc_encrypt(data.data(), baOutTmp.data(), (long)ANSILen - 8, &k1, &iv, DES_ENCRYPT); + } + uint8_t dest[8]; + DES_ede3_cbc_encrypt(data.mid(ANSILen - 8).data(), dest, (long)(data.size() - ANSILen) + 8, &k1, &k2, &k3, &iv, DES_ENCRYPT); + resp.copy(ByteArray(dest, 8)); + + return resp; + + exit_func +} + +CMAC::CMAC() { +} +#endif + + +CMAC::CMAC(const ByteArray &key, const ByteArray &iv) { + Init(key,iv); +} + diff --git a/libcie-pkcs11/Crypto/MD5.cpp b/libcie-pkcs11/Crypto/MD5.cpp index 77ff778b..54d2b727 100644 --- a/libcie-pkcs11/Crypto/MD5.cpp +++ b/libcie-pkcs11/Crypto/MD5.cpp @@ -1,84 +1,84 @@ - -#include "MD5.h" - -#ifdef WIN32 - -class init_md5 { - public: - BCRYPT_ALG_HANDLE algo; - init_md5() { - if (BCryptOpenAlgorithmProvider(&algo, BCRYPT_MD5_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0) != 0) - throw logged_error("Errore nell'inizializzazione dell'algoritmo MD5"); - } - ~init_md5() { - BCryptCloseAlgorithmProvider(algo, 0); - } -} algo_md5; - -CMD5::CMD5() : hash(nullptr) { -} - -CMD5::~CMD5() { - if (hash != nullptr) - BCryptDestroyHash(hash); -} -void CMD5::Init() { - if (hash != nullptr) - throw logged_error("Un'operazione di hash � gi� in corso"); - if (BCryptCreateHash(algo_md5.algo, &hash, nullptr, 0, nullptr, 0, 0) != 0) - throw logged_error("Errore nella creazione dell'hash SHA1"); -} -void CMD5::Update(ByteArray data) { - if (hash == nullptr) - throw logged_error("Hash non inizializzato"); - if (BCryptHashData(hash, data.data(), (ULONG)data.size(), 0) != 0) - throw logged_error("Errore nell'hash dei dati SHA1"); -} -ByteDynArray CMD5::Final() { - if (hash == nullptr) - throw logged_error("Hash non inizializzato"); - ByteDynArray resp(MD5_DIGEST_LENGTH); - if (BCryptFinishHash(hash, resp.data(), (ULONG)resp.size(), 0) != 0) - throw logged_error("Errore nel calcolo dell'hash SHA1"); - - BCryptDestroyHash(hash); - hash = nullptr; - - return resp; -} - -#else - -CMD5::CMD5() : isInit(false) { -} - -CMD5::~CMD5() { -} - -void CMD5::Init() { - //if (isInit) - // throw logged_error("Un'operazione di hash � gi� in corso"); - MD5_Init(&ctx); - isInit = true; -} -void CMD5::Update(ByteArray data) { - if (!isInit) - throw logged_error("Hash non inizializzato"); - MD5_Update(&ctx, data.data(), data.size()); -} -ByteDynArray CMD5::Final() { - if (!isInit) - throw logged_error("Hash non inizializzato"); - ByteDynArray resp(MD5_DIGEST_LENGTH); - MD5_Final(resp.data(), &ctx); - isInit = false; - - return resp; -} -#endif - -ByteDynArray CMD5::Digest(ByteArray data) { - Init(); - Update(data); - return Final(); -} + +#include "MD5.h" + +#ifdef WIN32 + +class init_md5 { + public: + BCRYPT_ALG_HANDLE algo; + init_md5() { + if (BCryptOpenAlgorithmProvider(&algo, BCRYPT_MD5_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0) != 0) + throw logged_error("Errore nell'inizializzazione dell'algoritmo MD5"); + } + ~init_md5() { + BCryptCloseAlgorithmProvider(algo, 0); + } +} algo_md5; + +CMD5::CMD5() : hash(nullptr) { +} + +CMD5::~CMD5() { + if (hash != nullptr) + BCryptDestroyHash(hash); +} +void CMD5::Init() { + if (hash != nullptr) + throw logged_error("Un'operazione di hash � gi� in corso"); + if (BCryptCreateHash(algo_md5.algo, &hash, nullptr, 0, nullptr, 0, 0) != 0) + throw logged_error("Errore nella creazione dell'hash SHA1"); +} +void CMD5::Update(ByteArray data) { + if (hash == nullptr) + throw logged_error("Hash non inizializzato"); + if (BCryptHashData(hash, data.data(), (ULONG)data.size(), 0) != 0) + throw logged_error("Errore nell'hash dei dati SHA1"); +} +ByteDynArray CMD5::Final() { + if (hash == nullptr) + throw logged_error("Hash non inizializzato"); + ByteDynArray resp(MD5_DIGEST_LENGTH); + if (BCryptFinishHash(hash, resp.data(), (ULONG)resp.size(), 0) != 0) + throw logged_error("Errore nel calcolo dell'hash SHA1"); + + BCryptDestroyHash(hash); + hash = nullptr; + + return resp; +} + +#else + +CMD5::CMD5() : isInit(false) { +} + +CMD5::~CMD5() { +} + +void CMD5::Init() { + //if (isInit) + // throw logged_error("Un'operazione di hash � gi� in corso"); + MD5_Init(&ctx); + isInit = true; +} +void CMD5::Update(ByteArray data) { + if (!isInit) + throw logged_error("Hash non inizializzato"); + MD5_Update(&ctx, data.data(), data.size()); +} +ByteDynArray CMD5::Final() { + if (!isInit) + throw logged_error("Hash non inizializzato"); + ByteDynArray resp(MD5_DIGEST_LENGTH); + MD5_Final(resp.data(), &ctx); + isInit = false; + + return resp; +} +#endif + +ByteDynArray CMD5::Digest(ByteArray data) { + Init(); + Update(data); + return Final(); +} diff --git a/libcie-pkcs11/Crypto/RSA.cpp b/libcie-pkcs11/Crypto/RSA.cpp index 9006d7b8..6af3e6bf 100644 --- a/libcie-pkcs11/Crypto/RSA.cpp +++ b/libcie-pkcs11/Crypto/RSA.cpp @@ -1,186 +1,186 @@ - -#include "RSA.h" -#include -#include "../Util/util.h" - -extern CLog Log; -#if (CRYPTOPP_VERSION >= 600) && (__cplusplus >= 201103L) -using byte = CryptoPP::byte; -#else -typedef unsigned char byte; -#endif - -#ifdef WIN32 - -class init_rsa { - public: - BCRYPT_ALG_HANDLE algo; - init_rsa() { - if (BCryptOpenAlgorithmProvider(&algo, BCRYPT_RSA_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0) != 0) - throw logged_error("Errore nell'inizializzazione dell'algoritmo RSA"); - } - ~init_rsa() { - BCryptCloseAlgorithmProvider(algo, 0); - } -} algo_rsa; - -CRSA::CRSA(ByteArray &mod, ByteArray &exp) { - KeySize = mod.size(); - ByteDynArray KeyData(sizeof(BCRYPT_RSAKEY_BLOB) + mod.size() + exp.size()); - BCRYPT_RSAKEY_BLOB *rsaImpKey = (BCRYPT_RSAKEY_BLOB *)KeyData.data(); - rsaImpKey->Magic = BCRYPT_RSAPUBLIC_MAGIC; - rsaImpKey->BitLength = (ULONG)(KeySize << 3); - rsaImpKey->cbModulus = (ULONG)KeySize; - rsaImpKey->cbPublicExp = (ULONG)exp.size(); - rsaImpKey->cbPrime1 = 0; - rsaImpKey->cbPrime2 = 0; - - KeyData.copy(exp, sizeof(BCRYPT_RSAKEY_BLOB)); - KeyData.rightcopy(mod); - - this->key = nullptr; - if (BCryptImportKeyPair(algo_rsa.algo, nullptr, BCRYPT_RSAPUBLIC_BLOB, &this->key, KeyData.data(), (ULONG)KeyData.size(), BCRYPT_NO_KEY_VALIDATION) != 0) - throw logged_error("Errore nella creazione della chiave RSA"); -} - -void CRSA::GenerateKey(DWORD size, ByteDynArray &module, ByteDynArray &pubexp, ByteDynArray &privexp) { - init_func - throw logged_error("Non supportato"); -} - -CRSA::~CRSA(void) { - if (key != nullptr) - BCryptDestroyKey(key); -} - -ByteDynArray CRSA::RSA_PURE(ByteArray &data) { - ULONG size = 0; - if (BCryptEncrypt(key, data.data(), (ULONG)data.size(), nullptr, nullptr, 0, nullptr, 0, &size, 0) != 0) - throw logged_error("Errore nella cifratura RSA"); - ByteDynArray resp(size); - if (BCryptEncrypt(key, data.data(), (ULONG)data.size(), nullptr, nullptr, 0, resp.data(), (ULONG)resp.size(), &size, 0) != 0) - throw logged_error("Errore nella cifratura RSA"); - - ER_ASSERT(size == KeySize, "Errore nella lunghezza dei dati per operazione RSA") - return resp; -} - -#else - -#include -#include -#include - -using CryptoPP::InvertibleRSAFunction; -using CryptoPP::RSASS; -using CryptoPP::RSA; -using CryptoPP::SHA512; -using CryptoPP::SecByteBlock; -using CryptoPP::PSS; -using CryptoPP::DecodingResult; - -DWORD CRSA::GenerateKey(DWORD size, ByteDynArray &module, ByteDynArray &pubexp, ByteDynArray &privexp) { - -#if 0 - keyPriv = RSA_new(); - auto BNpubexp = BN_new(); - BN_set_word(BNpubexp, 65537); - RSA_generate_key_ex(keyPriv, size, BNpubexp, nullptr); - module.resize(BN_num_bytes(keyPriv->n)); - .. - BN_bn2bin(keyPriv->n, module.data()); - privexp.resize(BN_num_bytes(keyPriv->d)); - BN_bn2bin(keyPriv->d, privexp.data()); - pubexp.resize(BN_num_bytes(keyPriv->e)); - BN_bn2bin(keyPriv->e, pubexp.data()); - - BN_clear_free(BNpubexp); - - return(S_OK); - exit_func - return(-1); -#endif - - init_func - throw logged_error("Non supportato"); - -} - -ByteArray modulusBa; -ByteArray exponentBa; - -CRSA::CRSA(ByteArray &mod,ByteArray &exp) { - modulusBa = mod; - exponentBa = exp; - - CryptoPP::Integer n(mod.data(), mod.size()), e(exp.data(), exp.size()); - pubKey.Initialize(n, e); - -#if 0 - ByteDynArray modBa(mod.size() + 1); - modBa.fill(0); - modBa.rightcopy(mod); - - ByteDynArray expBa(exp.size() + 1); - expBa.fill(0); - expBa.rightcopy(exp); - - KeySize = mod.size(); - keyPriv = RSA_new(); - keyPriv->n = BN_bin2bn(mod.data(), (int)mod.size(), keyPriv->n); - keyPriv->d = BN_new(); - keyPriv->e = BN_bin2bn(exp.data(), (int)exp.size(), keyPriv->e); -#endif - -} - -CRSA::~CRSA(void) { - //if (keyPriv!=nullptr) - // RSA_free(keyPriv); - -} - -ByteDynArray CRSA::RSA_PURE(ByteArray &data) { - -#if 0 - ByteDynArray resp(RSA_size(keyPriv)); - int SignSize = RSA_public_encrypt((int)data.size(), data.data(), resp.data(), keyPriv, RSA_NO_PADDING); - ER_ASSERT(SignSize == KeySize, "Errore nella lunghezza dei dati per operazione RSA") - - printf("\nRSA resp1: %s\n", dumpHexData(resp).c_str()); // DEBUG - - return resp; -#endif - - CryptoPP::Integer m((const byte *)data.data(), data.size()); - - CryptoPP::Integer c = pubKey.ApplyFunction(m); - - size_t len = c.MinEncodedSize(); - if (len == 0xff) - len = 0x100; - - ByteDynArray resp(len); - - c.Encode((byte *)resp.data(), resp.size(), CryptoPP::Integer::UNSIGNED); - - /*ULONG size = 0; - if (BCryptEncrypt(key, data.data(), (ULONG)data.size(), nullptr, nullptr, 0, nullptr, 0, &size, 0) != 0) - throw logged_error("Errore nella cifratura RSA"); - ByteDynArray resp1(size); - if (BCryptEncrypt(key, data.data(), (ULONG)data.size(), nullptr, nullptr, 0, resp1.data(), (ULONG)resp1.size(), &size, 0) != 0) - throw logged_error("Errore nella cifratura RSA"); - - ER_ASSERT(size == KeySize, "Errore nella lunghezza dei dati per operazione RSA")*/ - - return resp; -} - -bool CRSA::RSA_PSS(ByteArray &signatureData, ByteArray &toSign) { - RSASS::Verifier verifier(pubKey); - SecByteBlock signatureBlock((const byte*)signatureData.data(), signatureData.size()); - - return verifier.VerifyMessage((const byte*)toSign.data(), toSign.size(), signatureBlock, signatureBlock.size()); -} - -#endif + +#include "RSA.h" +#include +#include "../Util/util.h" + +extern CLog Log; +#if (CRYPTOPP_VERSION >= 600) && (__cplusplus >= 201103L) +using byte = CryptoPP::byte; +#else +typedef unsigned char byte; +#endif + +#ifdef WIN32 + +class init_rsa { + public: + BCRYPT_ALG_HANDLE algo; + init_rsa() { + if (BCryptOpenAlgorithmProvider(&algo, BCRYPT_RSA_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0) != 0) + throw logged_error("Errore nell'inizializzazione dell'algoritmo RSA"); + } + ~init_rsa() { + BCryptCloseAlgorithmProvider(algo, 0); + } +} algo_rsa; + +CRSA::CRSA(ByteArray &mod, ByteArray &exp) { + KeySize = mod.size(); + ByteDynArray KeyData(sizeof(BCRYPT_RSAKEY_BLOB) + mod.size() + exp.size()); + BCRYPT_RSAKEY_BLOB *rsaImpKey = (BCRYPT_RSAKEY_BLOB *)KeyData.data(); + rsaImpKey->Magic = BCRYPT_RSAPUBLIC_MAGIC; + rsaImpKey->BitLength = (ULONG)(KeySize << 3); + rsaImpKey->cbModulus = (ULONG)KeySize; + rsaImpKey->cbPublicExp = (ULONG)exp.size(); + rsaImpKey->cbPrime1 = 0; + rsaImpKey->cbPrime2 = 0; + + KeyData.copy(exp, sizeof(BCRYPT_RSAKEY_BLOB)); + KeyData.rightcopy(mod); + + this->key = nullptr; + if (BCryptImportKeyPair(algo_rsa.algo, nullptr, BCRYPT_RSAPUBLIC_BLOB, &this->key, KeyData.data(), (ULONG)KeyData.size(), BCRYPT_NO_KEY_VALIDATION) != 0) + throw logged_error("Errore nella creazione della chiave RSA"); +} + +void CRSA::GenerateKey(DWORD size, ByteDynArray &module, ByteDynArray &pubexp, ByteDynArray &privexp) { + init_func + throw logged_error("Non supportato"); +} + +CRSA::~CRSA(void) { + if (key != nullptr) + BCryptDestroyKey(key); +} + +ByteDynArray CRSA::RSA_PURE(ByteArray &data) { + ULONG size = 0; + if (BCryptEncrypt(key, data.data(), (ULONG)data.size(), nullptr, nullptr, 0, nullptr, 0, &size, 0) != 0) + throw logged_error("Errore nella cifratura RSA"); + ByteDynArray resp(size); + if (BCryptEncrypt(key, data.data(), (ULONG)data.size(), nullptr, nullptr, 0, resp.data(), (ULONG)resp.size(), &size, 0) != 0) + throw logged_error("Errore nella cifratura RSA"); + + ER_ASSERT(size == KeySize, "Errore nella lunghezza dei dati per operazione RSA") + return resp; +} + +#else + +#include +#include +#include + +using CryptoPP::InvertibleRSAFunction; +using CryptoPP::RSASS; +using CryptoPP::RSA; +using CryptoPP::SHA512; +using CryptoPP::SecByteBlock; +using CryptoPP::PSS; +using CryptoPP::DecodingResult; + +DWORD CRSA::GenerateKey(DWORD size, ByteDynArray &module, ByteDynArray &pubexp, ByteDynArray &privexp) { + +#if 0 + keyPriv = RSA_new(); + auto BNpubexp = BN_new(); + BN_set_word(BNpubexp, 65537); + RSA_generate_key_ex(keyPriv, size, BNpubexp, nullptr); + module.resize(BN_num_bytes(keyPriv->n)); + .. + BN_bn2bin(keyPriv->n, module.data()); + privexp.resize(BN_num_bytes(keyPriv->d)); + BN_bn2bin(keyPriv->d, privexp.data()); + pubexp.resize(BN_num_bytes(keyPriv->e)); + BN_bn2bin(keyPriv->e, pubexp.data()); + + BN_clear_free(BNpubexp); + + return(S_OK); + exit_func + return(-1); +#endif + + init_func + throw logged_error("Non supportato"); + +} + +ByteArray modulusBa; +ByteArray exponentBa; + +CRSA::CRSA(ByteArray &mod,ByteArray &exp) { + modulusBa = mod; + exponentBa = exp; + + CryptoPP::Integer n(mod.data(), mod.size()), e(exp.data(), exp.size()); + pubKey.Initialize(n, e); + +#if 0 + ByteDynArray modBa(mod.size() + 1); + modBa.fill(0); + modBa.rightcopy(mod); + + ByteDynArray expBa(exp.size() + 1); + expBa.fill(0); + expBa.rightcopy(exp); + + KeySize = mod.size(); + keyPriv = RSA_new(); + keyPriv->n = BN_bin2bn(mod.data(), (int)mod.size(), keyPriv->n); + keyPriv->d = BN_new(); + keyPriv->e = BN_bin2bn(exp.data(), (int)exp.size(), keyPriv->e); +#endif + +} + +CRSA::~CRSA(void) { + //if (keyPriv!=nullptr) + // RSA_free(keyPriv); + +} + +ByteDynArray CRSA::RSA_PURE(ByteArray &data) { + +#if 0 + ByteDynArray resp(RSA_size(keyPriv)); + int SignSize = RSA_public_encrypt((int)data.size(), data.data(), resp.data(), keyPriv, RSA_NO_PADDING); + ER_ASSERT(SignSize == KeySize, "Errore nella lunghezza dei dati per operazione RSA") + + printf("\nRSA resp1: %s\n", dumpHexData(resp).c_str()); // DEBUG + + return resp; +#endif + + CryptoPP::Integer m((const byte *)data.data(), data.size()); + + CryptoPP::Integer c = pubKey.ApplyFunction(m); + + size_t len = c.MinEncodedSize(); + if (len == 0xff) + len = 0x100; + + ByteDynArray resp(len); + + c.Encode((byte *)resp.data(), resp.size(), CryptoPP::Integer::UNSIGNED); + + /*ULONG size = 0; + if (BCryptEncrypt(key, data.data(), (ULONG)data.size(), nullptr, nullptr, 0, nullptr, 0, &size, 0) != 0) + throw logged_error("Errore nella cifratura RSA"); + ByteDynArray resp1(size); + if (BCryptEncrypt(key, data.data(), (ULONG)data.size(), nullptr, nullptr, 0, resp1.data(), (ULONG)resp1.size(), &size, 0) != 0) + throw logged_error("Errore nella cifratura RSA"); + + ER_ASSERT(size == KeySize, "Errore nella lunghezza dei dati per operazione RSA")*/ + + return resp; +} + +bool CRSA::RSA_PSS(ByteArray &signatureData, ByteArray &toSign) { + RSASS::Verifier verifier(pubKey); + SecByteBlock signatureBlock((const byte*)signatureData.data(), signatureData.size()); + + return verifier.VerifyMessage((const byte*)toSign.data(), toSign.size(), signatureBlock, signatureBlock.size()); +} + +#endif diff --git a/libcie-pkcs11/Crypto/SHA1.cpp b/libcie-pkcs11/Crypto/SHA1.cpp index f11cff68..d31d9036 100644 --- a/libcie-pkcs11/Crypto/SHA1.cpp +++ b/libcie-pkcs11/Crypto/SHA1.cpp @@ -1,86 +1,86 @@ - -#include "SHA1.h" - -#ifdef WIN32 - -static char *szCompiledFile=__FILE__; - -class init_sha1 { - public: - BCRYPT_ALG_HANDLE algo; - init_sha1() { - if (BCryptOpenAlgorithmProvider(&algo, BCRYPT_SHA1_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0) != 0) - throw logged_error("Errore nell'inizializzazione dell'algoritmo SHA1"); - } - ~init_sha1() { - BCryptCloseAlgorithmProvider(algo, 0); - } -} algo_sha1; - -CSHA1::CSHA1() : hash(nullptr) { -} - -CSHA1::~CSHA1() { - if (hash!=nullptr) - BCryptDestroyHash(hash); -} -void CSHA1::Init() { - if (hash != nullptr) - throw logged_error("Un'operazione di hash è già in corso"); - if (BCryptCreateHash(algo_sha1.algo, &hash, nullptr, 0, nullptr, 0, 0) != 0) - throw logged_error("Errore nella creazione dell'hash SHA1"); -} -void CSHA1::Update(ByteArray data) { - if (hash == nullptr) - throw logged_error("Hash non inizializzato"); - if (BCryptHashData(hash, data.data(), (ULONG)data.size(), 0) != 0) - throw logged_error("Errore nell'hash dei dati SHA1"); -} -ByteDynArray CSHA1::Final() { - if (hash == nullptr) - throw logged_error("Hash non inizializzato"); - ByteDynArray resp(SHA_DIGEST_LENGTH); - if (BCryptFinishHash(hash, resp.data(), (ULONG)resp.size(), 0) != 0) - throw logged_error("Errore nel calcolo dell'hash SHA1"); - - BCryptDestroyHash(hash); - hash = nullptr; - - return resp; -} - -#else - -CSHA1::CSHA1() : isInit(false) { -} - -CSHA1::~CSHA1() { -} - -void CSHA1::Init() { -// if (isInit) -// throw logged_error("Un'operazione di hash è già in corso"); - SHA1_Init(&ctx); - isInit = true; -} -void CSHA1::Update(ByteArray data) { - if (!isInit) - throw logged_error("Hash non inizializzato"); - SHA1_Update(&ctx, data.data(), data.size()); -} -ByteDynArray CSHA1::Final() { - if (!isInit) - throw logged_error("Hash non inizializzato"); - ByteDynArray resp(SHA_DIGEST_LENGTH); - SHA1_Final(resp.data(), &ctx); - isInit = false; - - return resp; -} -#endif - -ByteDynArray CSHA1::Digest(ByteArray data) { - Init(); - Update(data); - return Final(); -} + +#include "SHA1.h" + +#ifdef WIN32 + +static char *szCompiledFile=__FILE__; + +class init_sha1 { + public: + BCRYPT_ALG_HANDLE algo; + init_sha1() { + if (BCryptOpenAlgorithmProvider(&algo, BCRYPT_SHA1_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0) != 0) + throw logged_error("Errore nell'inizializzazione dell'algoritmo SHA1"); + } + ~init_sha1() { + BCryptCloseAlgorithmProvider(algo, 0); + } +} algo_sha1; + +CSHA1::CSHA1() : hash(nullptr) { +} + +CSHA1::~CSHA1() { + if (hash!=nullptr) + BCryptDestroyHash(hash); +} +void CSHA1::Init() { + if (hash != nullptr) + throw logged_error("Un'operazione di hash è già in corso"); + if (BCryptCreateHash(algo_sha1.algo, &hash, nullptr, 0, nullptr, 0, 0) != 0) + throw logged_error("Errore nella creazione dell'hash SHA1"); +} +void CSHA1::Update(ByteArray data) { + if (hash == nullptr) + throw logged_error("Hash non inizializzato"); + if (BCryptHashData(hash, data.data(), (ULONG)data.size(), 0) != 0) + throw logged_error("Errore nell'hash dei dati SHA1"); +} +ByteDynArray CSHA1::Final() { + if (hash == nullptr) + throw logged_error("Hash non inizializzato"); + ByteDynArray resp(SHA_DIGEST_LENGTH); + if (BCryptFinishHash(hash, resp.data(), (ULONG)resp.size(), 0) != 0) + throw logged_error("Errore nel calcolo dell'hash SHA1"); + + BCryptDestroyHash(hash); + hash = nullptr; + + return resp; +} + +#else + +CSHA1::CSHA1() : isInit(false) { +} + +CSHA1::~CSHA1() { +} + +void CSHA1::Init() { +// if (isInit) +// throw logged_error("Un'operazione di hash è già in corso"); + SHA1_Init(&ctx); + isInit = true; +} +void CSHA1::Update(ByteArray data) { + if (!isInit) + throw logged_error("Hash non inizializzato"); + SHA1_Update(&ctx, data.data(), data.size()); +} +ByteDynArray CSHA1::Final() { + if (!isInit) + throw logged_error("Hash non inizializzato"); + ByteDynArray resp(SHA_DIGEST_LENGTH); + SHA1_Final(resp.data(), &ctx); + isInit = false; + + return resp; +} +#endif + +ByteDynArray CSHA1::Digest(ByteArray data) { + Init(); + Update(data); + return Final(); +} diff --git a/libcie-pkcs11/Crypto/SHA256.cpp b/libcie-pkcs11/Crypto/SHA256.cpp index 03e3ae0f..63d46a77 100644 --- a/libcie-pkcs11/Crypto/SHA256.cpp +++ b/libcie-pkcs11/Crypto/SHA256.cpp @@ -1,76 +1,76 @@ - -#include "sha256.h" - -//static char *szCompiledFile=__FILE__; - -#ifdef WIN32 - -class init_sha256 { - public: - BCRYPT_ALG_HANDLE algo; - init_sha256() { - if (BCryptOpenAlgorithmProvider(&algo, BCRYPT_SHA256_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0) != 0) - throw logged_error("Errore nell'inizializzazione dell'algoritmo SHA256"); - } - ~init_sha256() { - BCryptCloseAlgorithmProvider(algo, 0); - } -} algo_sha256; - -ByteDynArray CSHA256::Digest(ByteArray &data) { - BCRYPT_HASH_HANDLE hash; - if (BCryptCreateHash(algo_sha256.algo, &hash, nullptr, 0, nullptr, 0, 0) != 0) - throw logged_error("Errore nella creazione dell'hash SHA256"); - ByteDynArray resp(SHA256_DIGEST_LENGTH); - if (BCryptHashData(hash, data.data(), (ULONG)data.size(), 0) != 0) - throw logged_error("Errore nell'hash dei dati SHA256"); - if (BCryptFinishHash(hash, resp.data(), (ULONG)resp.size(), 0) != 0) - throw logged_error("Errore nel calcolo dell'hash SHA256"); - BCryptDestroyHash(hash); - - return resp; -} - -#else - -#include -#include -#include - -void CSHA256::Init() { -// if (isInit) -// throw logged_error("Un'operazione di hash è già in corso"); - SHA256_Init(&ctx); - isInit = true; -} -void CSHA256::Update(ByteArray data) { - if (!isInit) - throw logged_error("Hash non inizializzato"); - SHA256_Update(&ctx, data.data(), data.size()); -} -ByteDynArray CSHA256::Final() { - if (!isInit) - throw logged_error("Hash non inizializzato"); - ByteDynArray resp(SHA_DIGEST_LENGTH); - SHA256_Final(resp.data(), &ctx); - isInit = false; - - return resp; -} -ByteDynArray CSHA256::Digest(ByteArray &data) { - const BYTE* pbData = (BYTE*) data.data(); - unsigned int nDataLen = data.size(); - BYTE abDigest[CryptoPP::SHA256::DIGESTSIZE]; - CryptoPP::SHA256().CalculateDigest(abDigest, pbData, nDataLen); - ByteArray resp(abDigest, CryptoPP::SHA256::DIGESTSIZE); - - -// ByteDynArray resp(SHA256_DIGEST_LENGTH); -// SHA256_Init(&ctx); -// SHA256_Update(&ctx, data.data(), data.size()); -// SHA256_Final(resp.data(), &ctx); -// //ER_ASSERT(SHA256(data.data(), data.size(), resp.data()) != NULL, "Errore nel calcolo dello SHA256") - - return resp; -} -#endif + +#include "sha256.h" + +//static char *szCompiledFile=__FILE__; + +#ifdef WIN32 + +class init_sha256 { + public: + BCRYPT_ALG_HANDLE algo; + init_sha256() { + if (BCryptOpenAlgorithmProvider(&algo, BCRYPT_SHA256_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0) != 0) + throw logged_error("Errore nell'inizializzazione dell'algoritmo SHA256"); + } + ~init_sha256() { + BCryptCloseAlgorithmProvider(algo, 0); + } +} algo_sha256; + +ByteDynArray CSHA256::Digest(ByteArray &data) { + BCRYPT_HASH_HANDLE hash; + if (BCryptCreateHash(algo_sha256.algo, &hash, nullptr, 0, nullptr, 0, 0) != 0) + throw logged_error("Errore nella creazione dell'hash SHA256"); + ByteDynArray resp(SHA256_DIGEST_LENGTH); + if (BCryptHashData(hash, data.data(), (ULONG)data.size(), 0) != 0) + throw logged_error("Errore nell'hash dei dati SHA256"); + if (BCryptFinishHash(hash, resp.data(), (ULONG)resp.size(), 0) != 0) + throw logged_error("Errore nel calcolo dell'hash SHA256"); + BCryptDestroyHash(hash); + + return resp; +} + +#else + +#include +#include +#include + +void CSHA256::Init() { +// if (isInit) +// throw logged_error("Un'operazione di hash è già in corso"); + SHA256_Init(&ctx); + isInit = true; +} +void CSHA256::Update(ByteArray data) { + if (!isInit) + throw logged_error("Hash non inizializzato"); + SHA256_Update(&ctx, data.data(), data.size()); +} +ByteDynArray CSHA256::Final() { + if (!isInit) + throw logged_error("Hash non inizializzato"); + ByteDynArray resp(SHA_DIGEST_LENGTH); + SHA256_Final(resp.data(), &ctx); + isInit = false; + + return resp; +} +ByteDynArray CSHA256::Digest(ByteArray &data) { + const BYTE* pbData = (BYTE*) data.data(); + unsigned int nDataLen = data.size(); + BYTE abDigest[CryptoPP::SHA256::DIGESTSIZE]; + CryptoPP::SHA256().CalculateDigest(abDigest, pbData, nDataLen); + ByteArray resp(abDigest, CryptoPP::SHA256::DIGESTSIZE); + + +// ByteDynArray resp(SHA256_DIGEST_LENGTH); +// SHA256_Init(&ctx); +// SHA256_Update(&ctx, data.data(), data.size()); +// SHA256_Final(resp.data(), &ctx); +// //ER_ASSERT(SHA256(data.data(), data.size(), resp.data()) != NULL, "Errore nel calcolo dello SHA256") + + return resp; +} +#endif diff --git a/libcie-pkcs11/LOGGER/Logger.cpp b/libcie-pkcs11/LOGGER/Logger.cpp new file mode 100644 index 00000000..cb411f5f --- /dev/null +++ b/libcie-pkcs11/LOGGER/Logger.cpp @@ -0,0 +1,414 @@ +#include "Logger.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +using namespace std; +using namespace CieIDLogger; + +inline bool config_exists(const string& name) { + ifstream f(name.c_str()); + return f.good(); +} + +Logger* Logger::m_Instance = 0; + +// Folder path string +// char szLogDir[PATH_MAX]; + +static const char* level_strings[] = {"", "[DEBUG]", "[INFO]", "[ERROR]"}; + +Logger::Logger() { + char pProcessInfo[PATH_MAX]; + + string sConfig; + char cTime[80]; + timeval curTime; + t_configTime = (time_t)0; + + // Initialize mutex + int ret = 0; + pthread_mutexattr_init(&m_Attr); + ret = pthread_mutexattr_settype(&m_Attr, PTHREAD_MUTEX_RECURSIVE); + if (ret != 0) { + printf("Logger::Logger() -- Mutex attribute not initialize!! Ret: %d\n", + ret); + + exit(0); + } + ret = pthread_mutex_init(&m_Mutex, &m_Attr); + if (ret != 0) { + printf("Logger::Logger() -- Mutex not initialize!!\n"); + exit(0); + } + + char* home = getenv("HOME"); + std::string path(home); + + path.append("/.CIEPKI/"); + + // check if folder exist + struct stat st = {0}; + + if (stat(path.c_str(), &st) == -1) { + mkdir(path.c_str(), 0700); + } + + gettimeofday(&curTime, NULL); + strftime(cTime, sizeof(cTime), "%Y-%m-%d", gmtime(&curTime.tv_sec)); + + sprintf(pbLog, "%s_%s.log", "CIEPKI", cTime); + path.append(pbLog); + + memcpy(pbLog, path.data(), path.length()); + pbLog[path.length()] = 0; + + int log_level = getLogConfig(); + + if (log_level == LOG_STATUS_DISABLED) { + disableLog(); + } else { + m_File.open(pbLog, ios::out | ios::app); + m_File + << endl + << "-----------------------------------------------------------------" + << endl + << endl; + + m_LogLevel = static_cast(log_level); + m_LogStatus = LOG_STATUS_ENABLED; + + /* + char cBuf [PATH_MAX]; + uint32_t bufsize = PATH_MAX; + + if(!_NSGetExecutablePath(cBuf, &bufsize)) + sprintf(pProcessInfo, "Process: '%s'", cBuf); + + m_File << pProcessInfo << endl; + */ + m_File.flush(); + m_File.close(); + } + + m_LogType = FILE_LOG; +} + +Logger::~Logger() { + m_File.close(); + pthread_mutexattr_destroy(&m_Attr); + pthread_mutex_destroy(&m_Mutex); +} + +Logger* Logger::getInstance() throw() { + if (m_Instance == 0) { + m_Instance = new Logger(); + } + + int log_level = m_Instance->getLogConfig(); + printf("Lib log level: %d\n", log_level); + + if (log_level == LOG_STATUS_DISABLED) { + m_Instance->disableLog(); + } else if (log_level > 0 && log_level < 3) { + m_Instance->enableFileLogging(); + m_Instance->enableLog(); + m_Instance->updateLogLevel(static_cast(log_level)); + } + + return m_Instance; +} + +void Logger::writeConfigFile(string& filePath, string& sConfig) throw() { + m_ConfigFile.open(filePath, ios::out); + m_ConfigFile << sConfig; + m_ConfigFile.close(); +} + +int Logger::getLogConfig() throw() { + char pbConfig[PATH_MAX]; + string sConfig; + int log_level; + struct stat result; + + char* home = getenv("HOME"); + std::string path(home); + + /* + if(path.find("/Library") == string::npos){ + path.append("/Library/Containers/it.ipzs.CIE-ID.CIEToken/Data"); + } + */ + + path.append("/.CIEPKI/"); + + // check if folder exist + struct stat st = {0}; + + if (stat(path.c_str(), &st) == -1) { + mkdir(path.c_str(), 0700); + } + + sprintf(pbConfig, "%s/config", path.data()); + + if (!config_exists(pbConfig)) { + sConfig = "LIB_LOG_LEVEL=2"; + string stConfig = string(pbConfig); + writeConfigFile(stConfig, sConfig); + t_configTime = 0; + } + + volatile int stat_res = stat(pbConfig, &result); + + if (stat_res == 0) { + if (t_configTime < result.st_mtime) { + t_configTime = result.st_mtime; + + lock(); + m_ConfigFile.open(pbConfig, ios::in); + m_ConfigFile >> sConfig; + m_ConfigFile.close(); + unlock(); + + sscanf(sConfig.data(), "LIB_LOG_LEVEL=%d", &log_level); + if (log_level < 0 && log_level > 3) { + log_level = 0; + sConfig = "LIB_LOG_LEVEL=2"; + string stConfig = string(pbConfig); + writeConfigFile(stConfig, sConfig); + } + + m_LogLevel = static_cast(log_level); + } + } + + return m_LogLevel; +} + +void Logger::lock() { + pthread_mutex_lock(&m_Mutex); +} + +void Logger::unlock() { + pthread_mutex_unlock(&m_Mutex); +} + +void Logger::logIntoFile(string& data) { + lock(); + m_File << getCurrentTime() << " " << data << endl; + unlock(); +} + +void Logger::logOnConsole(string& data) { + cout << getCurrentTime() << " " << data << endl; +} + +string Logger::getCurrentTime() { + char pbtDate[256]; + timeval curTime; + gettimeofday(&curTime, NULL); + int milli = curTime.tv_usec / 1000; + + strftime(pbtDate, sizeof(pbtDate), "%Y-%m-%d %H:%M:%S", + gmtime(&curTime.tv_sec)); + + sprintf(pbtDate, "%s:%03d", pbtDate, milli); + + return pbtDate; +} + +void Logger::log_log(ostream& out, LogLevel level, const char* text) throw() { + if (m_LogStatus == LOG_STATUS_ENABLED) { + if (level < m_LogLevel) { + return; + } + + string data; + data.append(level_strings[level]); + data.append(" "); + data.append(text); + + lock(); + m_File.open(pbLog, ios::out | ios::app); + m_File << getCurrentTime() << " " << data << endl; + m_File.flush(); + m_File.close(); + unlock(); + } +} + +// Interface for Debug Log +void Logger::debug(const char* fmt, ...) throw() { + char buffer[4096]; + va_list args; + va_start(args, fmt); + + vsprintf(buffer, fmt, args); + va_end(args); + + switch (m_LogType) { + case FILE_LOG: + log_log(m_File, LOG_LEVEL_DEBUG, buffer); + break; + case CONSOLE: + log_log(cout, LOG_LEVEL_DEBUG, buffer); + default: + break; + } +} + +void Logger::debug(string& text) throw() { + debug(text.data()); +} + +void Logger::debug(ostringstream& stream) throw() { + string text = stream.str(); + debug(text.data()); +} + +// Interface for Info Log +void Logger::info(const char* fmt, ...) throw() { + char buffer[1024]; + va_list args; + va_start(args, fmt); + + vsprintf(buffer, fmt, args); + va_end(args); + + switch (m_LogType) { + case FILE_LOG: + log_log(m_File, LOG_LEVEL_INFO, buffer); + break; + case CONSOLE: + log_log(cout, LOG_LEVEL_INFO, buffer); + default: + break; + } +} + +void Logger::info(string& text) throw() { + info(text.data()); +} + +void Logger::info(ostringstream& stream) throw() { + string text = stream.str(); + info(text.data()); +} + +// Interface for Error Log +int Logger::error(const char* fmt, ...) throw() { + char buffer[1024]; + va_list args; + va_start(args, fmt); + + vsprintf(buffer, fmt, args); + va_end(args); + + switch (m_LogType) { + case FILE_LOG: + log_log(m_File, LOG_LEVEL_ERROR, buffer); + break; + case CONSOLE: + log_log(cout, LOG_LEVEL_ERROR, buffer); + default: + break; + } + + return -1; +} + +int Logger::error(string& text) throw() { + return error(text.data()); +} + +int Logger::error(ostringstream& stream) throw() { + string text = stream.str(); + return error(text.data()); +} + +// Interface for Buffer Log +void Logger::buffer(uint8_t* buff, size_t buff_size) throw() { + if (m_LogLevel == LOG_LEVEL_DEBUG) { + switch (m_LogType) { + case FILE_LOG: + print_bytes(m_File, buff, buff_size, true); + break; + case CONSOLE: + print_bytes(cout, buff, buff_size, true); + default: + break; + } + } +} + +void Logger::print_bytes(ostream& out, uint8_t* data, size_t dataLen, + bool format) { + size_t index = 0; + + lock(); + m_File.open(pbLog, ios::out | ios::app); + + m_File << setfill('0'); + m_File << endl; + + m_File << "0x" << hex << setw(8) << index << "\t"; + + for (size_t index = 0; index < dataLen; index++) { + if (index) { + if ((index % 16) == 0) { + m_File << "\n0x" << hex << setw(8) << index << "\t"; + } else if ((index % 8) == 0) { + m_File << " - "; + } + } + + m_File << hex << setw(2) << (int)data[index] << " "; + } + m_File << endl << endl; + + m_File.close(); + unlock(); +} + +#if 0 +void Logger::buffer(string& text) throw() { + buffer(text.data()); +} + +void Logger::buffer(ostringstream& stream) throw() { + string text = stream.str(); + buffer(text.data()); +} +#endif + +void Logger::updateLogLevel(LogLevel logLevel) { + m_LogLevel = logLevel; +} + +void Logger::enableLog() { + m_LogStatus = LOG_STATUS_ENABLED; +} + +void Logger::disableLog() { + m_LogStatus = LOG_STATUS_DISABLED; +} + +void Logger::updateLogType(LogType logType) { + m_LogType = logType; +} + +void Logger::enableConsoleLogging() { + m_LogType = CONSOLE; +} + +void Logger::enableFileLogging() { + m_LogType = FILE_LOG; +} diff --git a/libcie-pkcs11/LOGGER/Logger.h b/libcie-pkcs11/LOGGER/Logger.h new file mode 100644 index 00000000..6966448a --- /dev/null +++ b/libcie-pkcs11/LOGGER/Logger.h @@ -0,0 +1,117 @@ +#ifndef _LOGGER_H_ +#define _LOGGER_H_ + +// C++ Header File(s) +#include +#include + +#include +#include +#include +#include + +#define MAX_PATH 1024 + +#define __time64_t __int64_t + +namespace CieIDLogger { +// Direct Interface for logging into log file or console using MACRO(s) +#define LOG_DEBUG(...) Logger::getInstance()->debug(__VA_ARGS__) +#define LOG_INFO(...) Logger::getInstance()->info(__VA_ARGS__) +#define LOG_ERROR(...) Logger::getInstance()->error(__VA_ARGS__) +#define LOG_BUFFER(data, len) Logger::getInstance()->buffer(data, len); + +typedef enum LOG_STATUS { + LOG_STATUS_DISABLED = 0, + LOG_STATUS_ENABLED = 1 +} LogStatus; + +// enum for LOG_LEVEL +typedef enum LOG_LEVEL { + LOG_LEVEL_DEBUG = 1, + LOG_LEVEL_INFO = 2, + LOG_LEVEL_ERROR = 3 +} LogLevel; + +// enum for LOG_TYPE +typedef enum LOG_TYPE { + NO_LOG = 1, + CONSOLE = 2, + FILE_LOG = 3, +} LogType; + +class Logger { + public: + static Logger* getInstance() throw(); + + // Interfaces to control log levels + void updateLogLevel(LogLevel logLevel); + void enableLog(); // Enable all log levels + void disableLog(); // Disable all log levels, except error and alarm + + // Interfaces to control log Types + void updateLogType(LogType logType); + + void enableConsoleLogging(); + void enableFileLogging(); + + // Interface for Debug log + void debug(const char* fmt, ...) throw(); + void debug(std::string& text) throw(); + void debug(std::ostringstream& stream) throw(); + + // Interface for Info Log + void info(const char* fmt, ...) throw(); + void info(std::string& text) throw(); + void info(std::ostringstream& stream) throw(); + + // Interface for Error Log + int error(const char* fmt, ...) throw(); + int error(std::string& text) throw(); + int error(std::ostringstream& stream) throw(); + + // Interface for Buffer Log + void buffer(uint8_t* buff, size_t buff_size) throw(); + // void buffer(std::string& text) throw(); + // void buffer(std::ostringstream& stream) throw(); + + protected: + Logger(); + ~Logger(); + + // Wrapper function for lock/unlock + // For Extensible feature, lock and unlock should be in protected + void lock(); + void unlock(); + + std::string getCurrentTime(); + int getLogConfig() throw(); + + private: + void logIntoFile(std::string& data); + void logOnConsole(std::string& data); + void log_log(std::ostream& out, LogLevel level, const char* text) throw(); + void writeConfigFile(std::string& filePath, std::string& sConfig) throw(); + void operator=(const Logger& obj) {} + + void print_bytes(std::ostream& out, uint8_t* data, size_t dataLen, + bool format); + + private: + static Logger* m_Instance; + std::ofstream m_File; + std::fstream m_ConfigFile; + char pbLog[MAX_PATH]; + char pbConfig[MAX_PATH]; + time_t t_configTime; + pthread_mutexattr_t m_Attr; + pthread_mutex_t m_Mutex; + + LogLevel m_LogLevel; + LogType m_LogType; + LogStatus m_LogStatus; +}; + +} // namespace CieIDLogger + +#endif // End of _LOGGER_H_ diff --git a/libcie-pkcs11/PCSC/APDU.cpp b/libcie-pkcs11/PCSC/APDU.cpp index 5d80f02f..2eb5d387 100644 --- a/libcie-pkcs11/PCSC/APDU.cpp +++ b/libcie-pkcs11/PCSC/APDU.cpp @@ -1,61 +1,61 @@ - -#include "APDU.h" -#include "../Util/TLV.h" -#include "../Util/util.h" -#include "../Crypto/DES3.h" -#include "../Crypto/MAC.h" -#include "Token.h" - -extern CLog Log; - -APDU::APDU() { -} -APDU::APDU(BYTE CLA,BYTE INS,BYTE P1,BYTE P2,BYTE LC,BYTE *pData,BYTE LE) { - init_func - if (LC>250) throw; - btINS=INS; - btCLA=CLA; - btP1=P1; - btP2=P2; - btLC=LC; - pbtData=pData; - btLE=LE; - bLC=true; - bLE=true; - exit_func -} -APDU::APDU(BYTE CLA,BYTE INS,BYTE P1,BYTE P2,BYTE LC,BYTE *pData) { - if (LC>251) throw; - btINS=INS; - btCLA=CLA; - btP1=P1; - btP2=P2; - btLC=LC; - pbtData=pData; - btLE=0; - bLC=true; - bLE=false; -} -APDU::APDU(BYTE CLA,BYTE INS,BYTE P1,BYTE P2,BYTE LE) { - btINS=INS; - btCLA=CLA; - btP1=P1; - btP2=P2; - btLE=LE; - btLC=0; - bLC=false; - bLE=true; -} -APDU::APDU(BYTE CLA,BYTE INS,BYTE P1,BYTE P2) { - btINS=INS; - btCLA=CLA; - btP1=P1; - btP2=P2; - btLE=0; - btLC=0; - bLC=false; - bLE=false; -} - -APDU::~APDU() { -} + +#include "APDU.h" +#include "../Util/TLV.h" +#include "../Util/util.h" +#include "../Crypto/DES3.h" +#include "../Crypto/MAC.h" +#include "Token.h" + +extern CLog Log; + +APDU::APDU() { +} +APDU::APDU(BYTE CLA,BYTE INS,BYTE P1,BYTE P2,BYTE LC,BYTE *pData,BYTE LE) { + init_func + if (LC>250) throw; + btINS=INS; + btCLA=CLA; + btP1=P1; + btP2=P2; + btLC=LC; + pbtData=pData; + btLE=LE; + bLC=true; + bLE=true; + exit_func +} +APDU::APDU(BYTE CLA,BYTE INS,BYTE P1,BYTE P2,BYTE LC,BYTE *pData) { + if (LC>251) throw; + btINS=INS; + btCLA=CLA; + btP1=P1; + btP2=P2; + btLC=LC; + pbtData=pData; + btLE=0; + bLC=true; + bLE=false; +} +APDU::APDU(BYTE CLA,BYTE INS,BYTE P1,BYTE P2,BYTE LE) { + btINS=INS; + btCLA=CLA; + btP1=P1; + btP2=P2; + btLE=LE; + btLC=0; + bLC=false; + bLE=true; +} +APDU::APDU(BYTE CLA,BYTE INS,BYTE P1,BYTE P2) { + btINS=INS; + btCLA=CLA; + btP1=P1; + btP2=P2; + btLE=0; + btLC=0; + bLC=false; + bLE=false; +} + +APDU::~APDU() { +} diff --git a/libcie-pkcs11/PCSC/CardLocker.cpp b/libcie-pkcs11/PCSC/CardLocker.cpp index 640f80eb..a438865e 100644 --- a/libcie-pkcs11/PCSC/CardLocker.cpp +++ b/libcie-pkcs11/PCSC/CardLocker.cpp @@ -1,30 +1,30 @@ - -#include "CardLocker.h" - -extern CLog Log; - -CCardLocker::CCardLocker(SCARDHANDLE card) { - hCard=card; - Lock(); -} - -CCardLocker::~CCardLocker(void) { - Unlock(); -} - -void CCardLocker::Lock() { - init_func - - SCardBeginTransaction(hCard); - - exit_func -} - -void CCardLocker::Unlock() { - init_func - - SCardEndTransaction(hCard,SCARD_LEAVE_CARD); - - exit_func -} - + +#include "CardLocker.h" + +extern CLog Log; + +CCardLocker::CCardLocker(SCARDHANDLE card) { + hCard=card; + Lock(); +} + +CCardLocker::~CCardLocker(void) { + Unlock(); +} + +void CCardLocker::Lock() { + init_func + + SCardBeginTransaction(hCard); + + exit_func +} + +void CCardLocker::Unlock() { + init_func + + SCardEndTransaction(hCard,SCARD_LEAVE_CARD); + + exit_func +} + diff --git a/libcie-pkcs11/PCSC/PCSC.cpp b/libcie-pkcs11/PCSC/PCSC.cpp index e27f3fc8..e0602c66 100644 --- a/libcie-pkcs11/PCSC/PCSC.cpp +++ b/libcie-pkcs11/PCSC/PCSC.cpp @@ -1,161 +1,161 @@ - -#include "PCSC.h" -#include "../Util/UtilException.h" -#include -#include - -struct transData { - SCARDCONTEXT context; - bool started; -}; -bool safeTransaction::isLocked() { - return locked; -} -safeTransaction::safeTransaction(safeConnection &conn, DWORD dwDisposition) { - this->hCard = conn.hCard; - this->dwDisposition = dwDisposition; - locked = false; - -// auto td = std::make_shared(); -// td->context = conn.hContext; -// td->started = false; -// auto thread = std::thread([td]() { -// for (int i = 0; i < 10; i++) { -// sleep(500); -// if (td->started) { -// return 0; -// } -// } -// SCardCancel(td->context); -// return 0; -// }); -// thread.detach(); - - - if (SCardBeginTransaction(hCard) != SCARD_S_SUCCESS) { - this->hCard = NULL; - this->dwDisposition = 0; - return; - } else { -// td->started = true; - locked = true; - } -} - -void safeTransaction::unlock() { - if (hCard != NULL && locked) { - SCardEndTransaction(hCard, dwDisposition); - locked = false; - } -} - -safeTransaction::~safeTransaction() { - if (hCard != NULL && locked) { - SCardEndTransaction(hCard, dwDisposition); - } -} - -safeConnection::safeConnection(SCARDHANDLE hCard) { - this->hCard = hCard; -} - -safeConnection::safeConnection(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode) { - DWORD dwProtocol; - this->hContext = hContext; - if (SCardConnect(hContext, szReader, dwShareMode, SCARD_PROTOCOL_T1, &hCard, &dwProtocol) != SCARD_S_SUCCESS) - hCard = NULL; -} - -safeConnection::~safeConnection() { - if (hCard) { - SCardDisconnect(hCard, SCARD_RESET_CARD); - } -} -safeConnection::operator SCARDHANDLE() { - return hCard; -} - -readerMonitor::~readerMonitor() { - stopMonitor = true; - SCardCancel(hContext); - Thread.join(); - SCardReleaseContext(hContext); -} - -readerMonitor::readerMonitor(void(*eventHandler)(std::string &reader, bool insert, void *appData), void *appData) : appData(appData) { - LONG _call_ris; - if ((_call_ris = (SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext))) != 0) { - throw windows_error(_call_ris); - } - stopMonitor = false; - readerEvent = eventHandler; - - Thread = std::thread([](readerMonitor *rm) -> DWORD { - std::vector readerList; - std::vector states; - - auto loadReaderList = [&]() -> void { - char *readers = nullptr; - unsigned long int len = 0; - -//#ifdef SCARD_AUTOALLOCATE -// DWORD dwReaders = SCARD_AUTOALLOCATE; -// -// if (SCardListReaders(rm->hContext, nullptr, (char*)&readers, &len) != SCARD_S_SUCCESS || readers == nullptr) { -// throw logged_error("Nessun lettore installato"); -// } -//#else - if(SCardListReaders(rm->hContext, NULL, NULL, &len)) - throw logged_error("Nessun lettore installato"); - - readers = (char*)calloc(len, sizeof(char)); - SCardListReaders(rm->hContext, NULL, readers, &len); -//#endif - - - const char *curReader = readers; - readerList.clear(); - for (; curReader[0] != 0; curReader += strnlen(curReader, len) + 1) - readerList.push_back(std::string(curReader)); -//#ifdef SCARD_AUTOALLOCATE -// SCardFreeMemory(rm->hContext, readers); -//#else - free(readers); -//#endif - states.resize((DWORD)readerList.size() + 1); - for (DWORD i = 0; i < readerList.size(); i++) { - states[i].szReader = readerList[i].c_str(); - } - auto &PnP = states[(DWORD)readerList.size()]; - PnP.szReader = "\\\\?PnP?\\Notification"; - PnP.pvUserData = (void*)PnP.szReader; - - SCardGetStatusChange(rm->hContext, 0, states.data(), states.size()); - for (DWORD i = 0; i < states.size(); i++) - states[i].dwCurrentState = states[i].dwEventState; - }; - loadReaderList(); - - while (!rm->stopMonitor) { - if (SCardGetStatusChange(rm->hContext, INFINITE, states.data(), states.size()) == SCARD_E_CANCELLED) - break; - for (DWORD i = 0; i < states.size(); i++) { - auto &state = states[i]; - if (state.pvUserData != nullptr && (state.dwEventState & SCARD_STATE_CHANGED) == SCARD_STATE_CHANGED) { - loadReaderList(); - break; - } - if (((state.dwCurrentState & SCARD_STATE_PRESENT) == SCARD_STATE_PRESENT) && - ((state.dwEventState & SCARD_STATE_PRESENT) == 0)) - rm->readerEvent(readerList[i], false, rm->appData); - - else if (((state.dwCurrentState & SCARD_STATE_PRESENT) == 0) && - ((state.dwEventState & SCARD_STATE_PRESENT) == SCARD_STATE_PRESENT)) - rm->readerEvent(readerList[i], true, rm->appData); - - state.dwCurrentState = state.dwEventState; - } - } - return 0; - }, this); -} + +#include "PCSC.h" +#include "../Util/UtilException.h" +#include +#include + +struct transData { + SCARDCONTEXT context; + bool started; +}; +bool safeTransaction::isLocked() { + return locked; +} +safeTransaction::safeTransaction(safeConnection &conn, DWORD dwDisposition) { + this->hCard = conn.hCard; + this->dwDisposition = dwDisposition; + locked = false; + +// auto td = std::make_shared(); +// td->context = conn.hContext; +// td->started = false; +// auto thread = std::thread([td]() { +// for (int i = 0; i < 10; i++) { +// sleep(500); +// if (td->started) { +// return 0; +// } +// } +// SCardCancel(td->context); +// return 0; +// }); +// thread.detach(); + + + if (SCardBeginTransaction(hCard) != SCARD_S_SUCCESS) { + this->hCard = NULL; + this->dwDisposition = 0; + return; + } else { +// td->started = true; + locked = true; + } +} + +void safeTransaction::unlock() { + if (hCard != NULL && locked) { + SCardEndTransaction(hCard, dwDisposition); + locked = false; + } +} + +safeTransaction::~safeTransaction() { + if (hCard != NULL && locked) { + SCardEndTransaction(hCard, dwDisposition); + } +} + +safeConnection::safeConnection(SCARDHANDLE hCard) { + this->hCard = hCard; +} + +safeConnection::safeConnection(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode) { + DWORD dwProtocol; + this->hContext = hContext; + if (SCardConnect(hContext, szReader, dwShareMode, SCARD_PROTOCOL_T1, &hCard, &dwProtocol) != SCARD_S_SUCCESS) + hCard = NULL; +} + +safeConnection::~safeConnection() { + if (hCard) { + SCardDisconnect(hCard, SCARD_RESET_CARD); + } +} +safeConnection::operator SCARDHANDLE() { + return hCard; +} + +readerMonitor::~readerMonitor() { + stopMonitor = true; + SCardCancel(hContext); + Thread.join(); + SCardReleaseContext(hContext); +} + +readerMonitor::readerMonitor(void(*eventHandler)(std::string &reader, bool insert, void *appData), void *appData) : appData(appData) { + LONG _call_ris; + if ((_call_ris = (SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext))) != 0) { + throw windows_error(_call_ris); + } + stopMonitor = false; + readerEvent = eventHandler; + + Thread = std::thread([](readerMonitor *rm) -> DWORD { + std::vector readerList; + std::vector states; + + auto loadReaderList = [&]() -> void { + char *readers = nullptr; + unsigned long int len = 0; + +//#ifdef SCARD_AUTOALLOCATE +// DWORD dwReaders = SCARD_AUTOALLOCATE; +// +// if (SCardListReaders(rm->hContext, nullptr, (char*)&readers, &len) != SCARD_S_SUCCESS || readers == nullptr) { +// throw logged_error("Nessun lettore installato"); +// } +//#else + if(SCardListReaders(rm->hContext, NULL, NULL, &len)) + throw logged_error("Nessun lettore installato"); + + readers = (char*)calloc(len, sizeof(char)); + SCardListReaders(rm->hContext, NULL, readers, &len); +//#endif + + + const char *curReader = readers; + readerList.clear(); + for (; curReader[0] != 0; curReader += strnlen(curReader, len) + 1) + readerList.push_back(std::string(curReader)); +//#ifdef SCARD_AUTOALLOCATE +// SCardFreeMemory(rm->hContext, readers); +//#else + free(readers); +//#endif + states.resize((DWORD)readerList.size() + 1); + for (DWORD i = 0; i < readerList.size(); i++) { + states[i].szReader = readerList[i].c_str(); + } + auto &PnP = states[(DWORD)readerList.size()]; + PnP.szReader = "\\\\?PnP?\\Notification"; + PnP.pvUserData = (void*)PnP.szReader; + + SCardGetStatusChange(rm->hContext, 0, states.data(), states.size()); + for (DWORD i = 0; i < states.size(); i++) + states[i].dwCurrentState = states[i].dwEventState; + }; + loadReaderList(); + + while (!rm->stopMonitor) { + if (SCardGetStatusChange(rm->hContext, INFINITE, states.data(), states.size()) == SCARD_E_CANCELLED) + break; + for (DWORD i = 0; i < states.size(); i++) { + auto &state = states[i]; + if (state.pvUserData != nullptr && (state.dwEventState & SCARD_STATE_CHANGED) == SCARD_STATE_CHANGED) { + loadReaderList(); + break; + } + if (((state.dwCurrentState & SCARD_STATE_PRESENT) == SCARD_STATE_PRESENT) && + ((state.dwEventState & SCARD_STATE_PRESENT) == 0)) + rm->readerEvent(readerList[i], false, rm->appData); + + else if (((state.dwCurrentState & SCARD_STATE_PRESENT) == 0) && + ((state.dwEventState & SCARD_STATE_PRESENT) == SCARD_STATE_PRESENT)) + rm->readerEvent(readerList[i], true, rm->appData); + + state.dwCurrentState = state.dwEventState; + } + } + return 0; + }, this); +} diff --git a/libcie-pkcs11/PCSC/Token.cpp b/libcie-pkcs11/PCSC/Token.cpp index 31ff70c3..7dfd1c49 100644 --- a/libcie-pkcs11/PCSC/Token.cpp +++ b/libcie-pkcs11/PCSC/Token.cpp @@ -1,139 +1,139 @@ - -#include "Token.h" -#include "APDU.h" -#include "../Util/TLV.h" -#include -#include - -extern CLog Log; - -CToken::CToken() { - transmitCallback=NULL; - transmitCallbackData=NULL; -} - -CToken::~CToken() { -} - - -void CToken::Reset(bool unpower) { - init_func - ER_ASSERT(transmitCallback!=nullptr, "Carta non Connessa") - - WORD reset = unpower ? 0xfffe : 0xffff; - StatusWord sw; - if ((sw = Transmit(VarToByteArray(reset), NULL)) != 0x9000) - printf("transmit error: %x", sw); -// throw scard_error(sw); -} - -void CToken::SelectMF() { - init_func - ER_ASSERT(transmitCallback!=nullptr,"Carta non Connessa") - - APDU apdu(0x00,0xA4,0x00,0x00); - StatusWord sw; - if ((sw = Transmit(apdu, NULL)) != 0x9000) - throw scard_error(sw); -} - - -ByteDynArray CToken::BinaryRead(WORD start,BYTE size) { - init_func - - std::vector dt; - - ER_ASSERT(transmitCallback,"Carta non Connessa") - - APDU apdu(0x00,0xB0,(BYTE)(start>>8),(BYTE)(start & 0xff),size); - ByteDynArray resp; - StatusWord sw; - if ((sw = Transmit(apdu, &resp)) != 0x9000) - throw scard_error(sw); - - return resp; -} - -StatusWord CToken::Transmit(ByteArray apdu, ByteDynArray *resp) { - init_func - - BYTE pbtResp[3000]; - DWORD dwResp = 3000; - HRESULT res = transmitCallback(transmitCallbackData, apdu.data(), apdu.size(), pbtResp, &dwResp); - ByteArray scResp(pbtResp, dwResp); - - if (res != SCARD_S_SUCCESS) { // la smart card è stata estratta durante l'operazione - printf("sc err %lx", res); - throw windows_error(res); - } - - if (scResp.size() < 2) - throw logged_error("Risposta della smart card non valida"); - - if (resp != nullptr) - *resp = scResp.left(scResp.size() - 2); - - auto sw = ByteArrayToVar(scResp.right(2).reverse(), uint16_t); - return sw; -} - -StatusWord CToken::Transmit(APDU &apdu, ByteDynArray *resp) { - init_func - - BYTE pbtAPDU[3000]; - BYTE pbtResp[3000]; - - ByteDynArray baSMData; - - int iAPDUSize = 0; - pbtAPDU[0] = apdu.btCLA; - pbtAPDU[1] = apdu.btINS; - pbtAPDU[2] = apdu.btP1; - pbtAPDU[3] = apdu.btP2; - if (apdu.bLC && apdu.bLE) { - iAPDUSize = apdu.btLC + 6; - pbtAPDU[4] = apdu.btLC; - CryptoPP::memcpy_s(pbtAPDU + 5, 2995, apdu.pbtData, apdu.btLC); - pbtAPDU[5 + apdu.btLC] = apdu.btLE; - } else if (apdu.bLC && !apdu.bLE) { - iAPDUSize = apdu.btLC + 5; - pbtAPDU[4] = apdu.btLC; - CryptoPP::memcpy_s(pbtAPDU + 5, 2995, apdu.pbtData, apdu.btLC); - } else if (!apdu.bLC && apdu.bLE) { - iAPDUSize = 5; - pbtAPDU[4] = apdu.btLE; - } else { // (!bLC && !bLE) - iAPDUSize = 4; - } - - DWORD dwResp = 3000; - HRESULT res = transmitCallback(transmitCallbackData, pbtAPDU, iAPDUSize, pbtResp, &dwResp); - ByteArray scResp(pbtResp, dwResp); - - if (res != SCARD_S_SUCCESS) // la smart card è stata estratta durante l'operazione - throw windows_error(res); - - if (scResp.size() < 2) - throw logged_error("Risposta della smart card non valida"); - - if (resp != nullptr) - *resp = scResp.left(scResp.size() - 2); - - auto sw = ByteArrayToVar(scResp.right(2).reverse(), uint16_t); - return sw; -} - -void CToken::setTransmitCallback(TokenTransmitCallback func,void *data) { - init_func - transmitCallback=func; - transmitCallbackData=data; -} - -void CToken::setTransmitCallbackData(void *data) { - init_func - transmitCallbackData = data; -} - -void *CToken::getTransmitCallbackData() { - return transmitCallbackData; -} + +#include "Token.h" +#include "APDU.h" +#include "../Util/TLV.h" +#include +#include + +extern CLog Log; + +CToken::CToken() { + transmitCallback=NULL; + transmitCallbackData=NULL; +} + +CToken::~CToken() { +} + + +void CToken::Reset(bool unpower) { + init_func + ER_ASSERT(transmitCallback!=nullptr, "Carta non Connessa") + + WORD reset = unpower ? 0xfffe : 0xffff; + StatusWord sw; + if ((sw = Transmit(VarToByteArray(reset), NULL)) != 0x9000) + printf("transmit error: %x", sw); +// throw scard_error(sw); +} + +void CToken::SelectMF() { + init_func + ER_ASSERT(transmitCallback!=nullptr,"Carta non Connessa") + + APDU apdu(0x00,0xA4,0x00,0x00); + StatusWord sw; + if ((sw = Transmit(apdu, NULL)) != 0x9000) + throw scard_error(sw); +} + + +ByteDynArray CToken::BinaryRead(WORD start,BYTE size) { + init_func + + std::vector dt; + + ER_ASSERT(transmitCallback,"Carta non Connessa") + + APDU apdu(0x00,0xB0,(BYTE)(start>>8),(BYTE)(start & 0xff),size); + ByteDynArray resp; + StatusWord sw; + if ((sw = Transmit(apdu, &resp)) != 0x9000) + throw scard_error(sw); + + return resp; +} + +StatusWord CToken::Transmit(ByteArray apdu, ByteDynArray *resp) { + init_func + + BYTE pbtResp[3000]; + DWORD dwResp = 3000; + HRESULT res = transmitCallback(transmitCallbackData, apdu.data(), apdu.size(), pbtResp, &dwResp); + ByteArray scResp(pbtResp, dwResp); + + if (res != SCARD_S_SUCCESS) { // la smart card è stata estratta durante l'operazione + printf("sc err %lx", res); + throw windows_error(res); + } + + if (scResp.size() < 2) + throw logged_error("Risposta della smart card non valida"); + + if (resp != nullptr) + *resp = scResp.left(scResp.size() - 2); + + auto sw = ByteArrayToVar(scResp.right(2).reverse(), uint16_t); + return sw; +} + +StatusWord CToken::Transmit(APDU &apdu, ByteDynArray *resp) { + init_func + + BYTE pbtAPDU[3000]; + BYTE pbtResp[3000]; + + ByteDynArray baSMData; + + int iAPDUSize = 0; + pbtAPDU[0] = apdu.btCLA; + pbtAPDU[1] = apdu.btINS; + pbtAPDU[2] = apdu.btP1; + pbtAPDU[3] = apdu.btP2; + if (apdu.bLC && apdu.bLE) { + iAPDUSize = apdu.btLC + 6; + pbtAPDU[4] = apdu.btLC; + CryptoPP::memcpy_s(pbtAPDU + 5, 2995, apdu.pbtData, apdu.btLC); + pbtAPDU[5 + apdu.btLC] = apdu.btLE; + } else if (apdu.bLC && !apdu.bLE) { + iAPDUSize = apdu.btLC + 5; + pbtAPDU[4] = apdu.btLC; + CryptoPP::memcpy_s(pbtAPDU + 5, 2995, apdu.pbtData, apdu.btLC); + } else if (!apdu.bLC && apdu.bLE) { + iAPDUSize = 5; + pbtAPDU[4] = apdu.btLE; + } else { // (!bLC && !bLE) + iAPDUSize = 4; + } + + DWORD dwResp = 3000; + HRESULT res = transmitCallback(transmitCallbackData, pbtAPDU, iAPDUSize, pbtResp, &dwResp); + ByteArray scResp(pbtResp, dwResp); + + if (res != SCARD_S_SUCCESS) // la smart card è stata estratta durante l'operazione + throw windows_error(res); + + if (scResp.size() < 2) + throw logged_error("Risposta della smart card non valida"); + + if (resp != nullptr) + *resp = scResp.left(scResp.size() - 2); + + auto sw = ByteArrayToVar(scResp.right(2).reverse(), uint16_t); + return sw; +} + +void CToken::setTransmitCallback(TokenTransmitCallback func,void *data) { + init_func + transmitCallback=func; + transmitCallbackData=data; +} + +void CToken::setTransmitCallbackData(void *data) { + init_func + transmitCallbackData = data; +} + +void *CToken::getTransmitCallbackData() { + return transmitCallbackData; +} diff --git a/libcie-pkcs11/PKCS11/CIEP11Template.cpp b/libcie-pkcs11/PKCS11/CIEP11Template.cpp index 5099a2e2..6334ab30 100644 --- a/libcie-pkcs11/PKCS11/CIEP11Template.cpp +++ b/libcie-pkcs11/PKCS11/CIEP11Template.cpp @@ -1,772 +1,772 @@ - -#include "CIEP11Template.h" -#include "../CSP/IAS.h" -#include "../PCSC/CardLocker.h" -#include "../Crypto/ASNParser.h" -#include "../Crypto/AES.h" -#include "../PCSC/PCSC.h" -#include -#include -#include "../Util/CryptoppUtils.h" -#include - -extern CLog Log; - -using namespace CryptoPP; -using namespace lcp; - -void notifyPINLocked(); -void notifyPINWrong(int trials); - -void GetCertInfo(CryptoPP::BufferedTransformation & certin, - std::string & serial, - CryptoPP::BufferedTransformation & issuer, - CryptoPP::BufferedTransformation & subject, - std::string & notBefore, - std::string & notAfter, - CryptoPP::Integer& mod, - CryptoPP::Integer& pubExp); - -int TokenTransmitCallback(CSlot *data, BYTE *apdu, DWORD apduSize, BYTE *resp, DWORD *respSize) { - if (apduSize == 2) { - WORD code = *(WORD*)apdu; - if (code == 0xfffd) { - long bufLen = *respSize; - *respSize = sizeof(data->hCard)+2; - CryptoPP::memcpy_s(resp, bufLen, &data->hCard, sizeof(data->hCard)); - resp[sizeof(data->hCard)] = 0; - resp[sizeof(data->hCard) + 1] = 0; - - return SCARD_S_SUCCESS; - } else if (code == 0xfffe) { - DWORD protocol = 0; - ODS("%s", "UNPOWER CARD"); - auto ris = SCardReconnect(data->hCard, SCARD_SHARE_SHARED, SCARD_PROTOCOL_Tx, SCARD_UNPOWER_CARD, &protocol); - - - if (ris == SCARD_S_SUCCESS) { - SCardBeginTransaction(data->hCard); - *respSize = 2; - resp[0] = 0x90; - resp[1] = 0x00; - } - return ris; - } else if (code == 0xffff) { - DWORD protocol = 0; - auto ris = SCardReconnect(data->hCard, SCARD_SHARE_SHARED, SCARD_PROTOCOL_Tx, SCARD_RESET_CARD, &protocol); - if (ris == SCARD_S_SUCCESS) { - SCardBeginTransaction(data->hCard); - *respSize = 2; - resp[0] = 0x90; - resp[1] = 0x00; - } - ODS("%s", "RESET CARD"); - return ris; - } - } - - Log.writePure("APDU: %s", dumpHexData(ByteArray(apdu, apduSize)).c_str()); - - //ODS("%s", String().printf("APDU: %s\n", dumpHexData(ByteArray(apdu, apduSize), String()).lock()).lock()); - auto ris = SCardTransmit(data->hCard, SCARD_PCI_T1, apdu, apduSize, NULL, resp, respSize); - if(ris == SCARD_W_RESET_CARD || ris == SCARD_W_UNPOWERED_CARD) { - Log.writePure("Errore card reset: %x", ris); - ODS("%s", "card resetted"); - DWORD protocol = 0; - ris = SCardReconnect(data->hCard, SCARD_SHARE_SHARED, SCARD_PROTOCOL_Tx, SCARD_LEAVE_CARD, &protocol); - if (ris != SCARD_S_SUCCESS) { - ODS("%s", "Errore reconnect"); - Log.writePure("Errore reconnect: %x", ris); - } else - ris = SCardTransmit(data->hCard, SCARD_PCI_T1, apdu, apduSize, NULL, resp, respSize); - } - - if (ris != SCARD_S_SUCCESS) { - Log.writePure("Errore trasmissione APDU: %x", ris); - ODS("%s", "Errore trasmissione APDU"); - } - //else - //ODS("%s", String().printf("RESP: %s\n", dumpHexData(ByteArray(resp, *respSize), String()).lock()).lock()); - - return ris; -} - -class CIEData { - public: - CK_USER_TYPE userType; - CAES aesKey; - CToken token; - bool init; - CIEData(CSlot *slot,ByteArray atr) : ias((CToken::TokenTransmitCallback)TokenTransmitCallback,atr), slot(*slot) { - ByteDynArray key(32); - ByteDynArray iv(16); - aesKey.Init(key.random(),iv.random()); - token.setTransmitCallbackData(slot); - userType = -1; - init = false; - } - CSlot &slot; - IAS ias; - std::shared_ptr pubKey; - std::shared_ptr privKey; - std::shared_ptr cert; - ByteDynArray SessionPIN; -}; - -void CIEtemplateInitLibrary(class CCardTemplate &Template, void *templateData) { - return; -} -void CIEtemplateInitCard(void *&pTemplateData, CSlot &pSlot) { - init_func - ByteArray ATR; - pSlot.GetATR(ATR); - - pTemplateData = new CIEData(&pSlot, ATR); -} -void CIEtemplateFinalCard(void *pTemplateData) { - if (pTemplateData) - delete (CIEData*)pTemplateData; -} - -ByteArray SkipZero(ByteArray &ba) { - for (DWORD i = 0; i < ba.size(); i++) { - if (ba[i] != 0) - return ba.mid(i); - } - return ByteArray(); -} - -BYTE label[] = { 'C','I','E','0' }; -void CIEtemplateInitSession(void *pTemplateData) { - CIEData* cie=(CIEData*)pTemplateData; - - if (!cie->init) { - ByteDynArray certRaw; - cie->slot.Connect(); - { - safeConnection faseConn(cie->slot.hCard); - CCardLocker lockCard(cie->slot.hCard); - cie->ias.SetCardContext(&cie->slot); - cie->ias.SelectAID_IAS(); - cie->ias.ReadPAN(); - - ByteDynArray resp; - cie->ias.SelectAID_CIE(); - cie->ias.ReadDappPubKey(resp); - cie->ias.InitEncKey(); - cie->ias.GetCertificate(certRaw, true); - } - - - CK_BBOOL vtrue = TRUE; - CK_BBOOL vfalse = FALSE; - - cie->pubKey = std::make_shared(cie); - cie->privKey = std::make_shared(cie); - cie->cert = std::make_shared(cie); - - cie->pubKey->addAttribute(CKA_LABEL, VarToByteArray(label)); - cie->pubKey->addAttribute(CKA_ID, VarToByteArray(label)); - cie->pubKey->addAttribute(CKA_PRIVATE, VarToByteArray(vfalse)); - cie->pubKey->addAttribute(CKA_TOKEN, VarToByteArray(vtrue)); - cie->pubKey->addAttribute(CKA_VERIFY, VarToByteArray(vtrue)); - CK_KEY_TYPE keyrsa = CKK_RSA; - cie->pubKey->addAttribute(CKA_KEY_TYPE, VarToByteArray(keyrsa)); - - cie->privKey->addAttribute(CKA_LABEL, VarToByteArray(label)); - cie->privKey->addAttribute(CKA_ID, VarToByteArray(label)); - cie->privKey->addAttribute(CKA_PRIVATE, VarToByteArray(vtrue)); - cie->privKey->addAttribute(CKA_TOKEN, VarToByteArray(vtrue)); - cie->privKey->addAttribute(CKA_KEY_TYPE, VarToByteArray(keyrsa)); - - cie->privKey->addAttribute(CKA_SIGN, VarToByteArray(vtrue)); - - cie->cert->addAttribute(CKA_LABEL, VarToByteArray(label)); - cie->cert->addAttribute(CKA_ID, VarToByteArray(label)); - cie->cert->addAttribute(CKA_PRIVATE, VarToByteArray(vfalse)); - cie->cert->addAttribute(CKA_TOKEN, VarToByteArray(vtrue)); - - CK_CERTIFICATE_TYPE certx509 = CKC_X_509; - cie->cert->addAttribute(CKA_CERTIFICATE_TYPE, VarToByteArray(certx509)); - - Log.write(dumpHexData(certRaw).c_str()); - -#ifdef WIN32 - PCCERT_CONTEXT certDS = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, certRaw.data(), (DWORD)certRaw.size()); - if (certDS != nullptr) { - auto _1 = scopeExit([&]() noexcept { - CertFreeCertificateContext(certDS); - }); - - - - CASNParser keyParser; - keyParser.Parse(ByteArray(certDS->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData, certDS->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData)); - auto Module = SkipZero(keyParser.tags[0]->tags[0]->content); - auto Exponent = SkipZero(keyParser.tags[0]->tags[1]->content); - CK_LONG keySizeBits = (CK_LONG)Module.size() * 8; - - cie->pubKey->addAttribute(CKA_MODULUS, Module); - cie->pubKey->addAttribute(CKA_PUBLIC_EXPONENT, Exponent); - cie->pubKey->addAttribute(CKA_MODULUS_BITS, VarToByteArray(keySizeBits)); - - - - - cie->privKey->addAttribute(CKA_MODULUS, Module); - cie->privKey->addAttribute(CKA_PUBLIC_EXPONENT, Exponent); - - cie->cert->addAttribute(CKA_ISSUER, ByteArray(certDS->pCertInfo->Issuer.pbData, certDS->pCertInfo->Issuer.cbData)); - cie->cert->addAttribute(CKA_SERIAL_NUMBER, ByteArray(certDS->pCertInfo->SerialNumber.pbData, certDS->pCertInfo->SerialNumber.cbData)); - cie->cert->addAttribute(CKA_SUBJECT, ByteArray(certDS->pCertInfo->Subject.pbData, certDS->pCertInfo->Subject.cbData)); - - CK_DATE start, end; - SYSTEMTIME sFrom, sTo; - char temp[10]; - if (!FileTimeToSystemTime(&certDS->pCertInfo->NotBefore, &sFrom)) - throw logged_error("Errore nella data di inizio validita' certificato"); - if (!FileTimeToSystemTime(&certDS->pCertInfo->NotAfter, &sTo)) - throw logged_error("Errore nella data di fine validita' certificato"); - snprintf_s(temp, 10, "%04i", sFrom.wYear); - VarToByteArray(start.year).copy(ByteArray((BYTE*)temp, 4)); - snprintf_s(temp, 10, "%02i", sFrom.wMonth); - VarToByteArray(start.month).copy(ByteArray((BYTE*)temp, 2)); - snprintf_s(temp, 10, "%02i", sFrom.wDay); - VarToByteArray(start.day).copy(ByteArray((BYTE*)temp, 2)); - snprintf_s(temp, 10, "%04i", sTo.wYear); - VarToByteArray(end.year).copy(ByteArray((BYTE*)temp, 2)); - snprintf_s(temp, 10, "%02i", sTo.wMonth); - VarToByteArray(end.month).copy(ByteArray((BYTE*)temp, 2)); - snprintf_s(temp, 10, "%02i", sTo.wDay); - VarToByteArray(end.day).copy(ByteArray((BYTE*)temp, 2)); - cie->cert->addAttribute(CKA_START_DATE, VarToByteArray(start)); - cie->cert->addAttribute(CKA_END_DATE, VarToByteArray(end)); - } -#else - // TODO decode the certificate - - // not before - // not after - // modulus - // public exponent - // issuer - // serialnumber - // subject - - CryptoPP::ByteQueue certin; - certin.Put(certRaw.data(),certRaw.size()); - - - - std::string serial; - CryptoPP::ByteQueue issuer; - CryptoPP::ByteQueue subject; - std::string notBefore; - std::string notAfter; - CryptoPP::Integer mod; - CryptoPP::Integer pubExp; - - GetCertInfo(certin, serial, issuer, subject, notBefore, notAfter, mod, pubExp); - - ByteDynArray modulus(mod.ByteCount()); - mod.Encode(modulus.data(), modulus.size()); - - ByteDynArray publicExponent(pubExp.ByteCount()); - pubExp.Encode(publicExponent.data(), publicExponent.size()); - - CK_LONG keySizeBits = (CK_LONG)modulus.size() * 8; - - cie->pubKey->addAttribute(CKA_MODULUS, modulus); - cie->pubKey->addAttribute(CKA_PUBLIC_EXPONENT, publicExponent); - cie->pubKey->addAttribute(CKA_MODULUS_BITS, VarToByteArray(keySizeBits)); - - cie->privKey->addAttribute(CKA_MODULUS, modulus); - cie->privKey->addAttribute(CKA_PUBLIC_EXPONENT, publicExponent); - - ByteDynArray issuerBa(issuer.CurrentSize()); - issuer.Get(issuerBa.data(), issuerBa.size()); - - ByteDynArray subjectBa(subject.CurrentSize()); - subject.Get(subjectBa.data(), subjectBa.size()); - - cie->cert->addAttribute(CKA_ISSUER, issuerBa); - cie->cert->addAttribute(CKA_SERIAL_NUMBER, ByteArray((BYTE*)serial.c_str(), serial.size())); - cie->cert->addAttribute(CKA_SUBJECT, subjectBa); - - - CK_DATE start, end; - - SYSTEMTIME sFrom, sTo; - sFrom = convertStringToSystemTime(notBefore.c_str()); - sTo = convertStringToSystemTime(notAfter.c_str()); - - cie->cert->addAttribute(CKA_START_DATE, VarToByteArray(start)); - cie->cert->addAttribute(CKA_END_DATE, VarToByteArray(end)); - - // add to the object -#endif - - size_t len = GetASN1DataLenght(certRaw); - cie->cert->addAttribute(CKA_VALUE, certRaw.left(len)); - - cie->slot.AddP11Object(cie->pubKey); - cie->slot.AddP11Object(cie->privKey); - cie->slot.AddP11Object(cie->cert); - - cie->init = true; - } -} -void CIEtemplateFinalSession(void *pTemplateData) { - //delete (CIEData*)pTemplateData; -} - -bool CIEtemplateMatchCard(CSlot &pSlot) { - init_func - CToken token; - - pSlot.Connect(); - { - safeConnection faseConn(pSlot.hCard); - ByteArray ATR; - pSlot.GetATR(ATR); - token.setTransmitCallback((CToken::TokenTransmitCallback)TokenTransmitCallback, &pSlot); - IAS ias((CToken::TokenTransmitCallback)TokenTransmitCallback, ATR); - ias.SetCardContext(&pSlot); - { - safeTransaction trans(faseConn,SCARD_LEAVE_CARD); - ias.SelectAID_IAS(); - ias.ReadPAN(); - } - return true; - } -} - -ByteDynArray CIEtemplateGetSerial(CSlot &pSlot) { - init_func - CToken token; - - pSlot.Connect(); - { - safeConnection faseConn(pSlot.hCard); - CCardLocker lockCard(pSlot.hCard); - ByteArray ATR; - pSlot.GetATR(ATR); - IAS ias((CToken::TokenTransmitCallback)TokenTransmitCallback, ATR); - ias.SetCardContext(&pSlot); - ias.SelectAID_IAS(); - ias.ReadPAN(); - std::string numSerial; - dumpHexData(ias.PAN.mid(5, 6), numSerial, false); - return ByteArray((BYTE*)numSerial.c_str(),numSerial.length()); - } -} -void CIEtemplateGetModel(CSlot &pSlot, std::string &szModel) { - szModel = ""; -} -void CIEtemplateGetTokenFlags(CSlot &pSlot, CK_FLAGS &dwFlags) { - dwFlags = CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED | CKF_TOKEN_INITIALIZED | CKF_REMOVABLE_DEVICE; -} - -void CIEtemplateLogin(void *pTemplateData, CK_USER_TYPE userType, ByteArray &Pin) { - init_func - CToken token; - CIEData* cie = (CIEData*)pTemplateData; - - cie->SessionPIN.clear(); - cie->userType = -1; - - cie->slot.Connect(); - cie->ias.SetCardContext(&cie->slot); - cie->ias.token.Reset(); - { - safeConnection safeConn(cie->slot.hCard); - CCardLocker lockCard(cie->slot.hCard); - - cie->ias.SelectAID_IAS(); - cie->ias.SelectAID_CIE(); - cie->ias.InitDHParam(); - - if (cie->ias.DappPubKey.isEmpty()) { - ByteDynArray DappKey; - cie->ias.ReadDappPubKey(DappKey); - } - - cie->ias.InitExtAuthKeyParam(); - // faccio lo scambio di chiavi DH - if (cie->ias.Callback != nullptr) - cie->ias.Callback(1, "DiffieHellman", cie->ias.CallbackData); - cie->ias.DHKeyExchange(); - // DAPP - if (cie->ias.Callback != nullptr) - cie->ias.Callback(2, "DAPP", cie->ias.CallbackData); - cie->ias.DAPP(); - // verifica PIN - StatusWord sw; - if (cie->ias.Callback != nullptr) - cie->ias.Callback(3, "Verify PIN", cie->ias.CallbackData); - if (userType == CKU_USER) { - ByteDynArray FullPIN; - cie->ias.GetFirstPIN(FullPIN); - FullPIN.append(Pin); - sw = cie->ias.VerifyPIN(FullPIN); - } else if (userType == CKU_SO) { - sw = cie->ias.VerifyPUK(Pin); - } else - throw p11_error(CKR_ARGUMENTS_BAD); - - if (sw == 0x6983) { - if (userType == CKU_USER) { - notifyPINLocked(); - //cie->ias.IconaSbloccoPIN(); - throw p11_error(CKR_PIN_LOCKED); - } - } - if (sw >= 0x63C0 && sw <= 0x63CF) { - int attemptsRemaining = sw - 0x63C0; - notifyPINWrong(attemptsRemaining); - throw p11_error(CKR_PIN_INCORRECT); - } - if (sw == 0x6700) { - notifyPINWrong(-1); - throw p11_error(CKR_PIN_INCORRECT); - } - if (sw == 0x6300) { - notifyPINWrong(-1); - throw p11_error(CKR_PIN_INCORRECT); - } - if (sw != 0x9000) { - throw scard_error(sw); - } - - cie->SessionPIN = cie->aesKey.Encode(Pin); - cie->userType = userType; - } -} -void CIEtemplateLogout(void *pTemplateData, CK_USER_TYPE userType) { - CIEData* cie = (CIEData*)pTemplateData; - cie->userType = -1; - cie->SessionPIN.clear(); -} -void CIEtemplateReadObjectAttributes(void *pCardTemplateData, CP11Object *pObject) { -} -void CIEtemplateSign(void *pCardTemplateData, CP11PrivateKey *pPrivKey, ByteArray &baSignBuffer, ByteDynArray &baSignature, CK_MECHANISM_TYPE mechanism, bool bSilent) { - init_func - CToken token; - CIEData* cie = (CIEData*)pCardTemplateData; - if (cie->userType == CKU_USER) { - ByteDynArray Pin; - cie->slot.Connect(); - cie->ias.SetCardContext(&cie->slot); - cie->ias.token.Reset(); - { - safeConnection safeConn(cie->slot.hCard); - CCardLocker lockCard(cie->slot.hCard); - - Pin = cie->aesKey.Decode(cie->SessionPIN); - cie->ias.SelectAID_IAS(); - cie->ias.SelectAID_CIE(); - cie->ias.DHKeyExchange(); - cie->ias.DAPP(); - - ByteDynArray FullPIN; - cie->ias.GetFirstPIN(FullPIN); - FullPIN.append(Pin); - if (cie->ias.VerifyPIN(FullPIN) != 0x9000) - throw p11_error(CKR_PIN_INCORRECT); - cie->ias.Sign(baSignBuffer, baSignature); - } - } -} - -void CIEtemplateInitPIN(void *pCardTemplateData, ByteArray &baPin) { - init_func - CToken token; - CIEData* cie = (CIEData*)pCardTemplateData; - if (cie->userType == CKU_SO) { - // posso usarla solo se sono loggato come so - ByteDynArray Pin; - cie->slot.Connect(); - cie->ias.SetCardContext(&cie->slot); - cie->ias.token.Reset(); - { - safeConnection safeConn(cie->slot.hCard); - CCardLocker lockCard(cie->slot.hCard); - - Pin = cie->aesKey.Decode(cie->SessionPIN); - cie->ias.SelectAID_IAS(); - cie->ias.SelectAID_CIE(); - - cie->ias.DHKeyExchange(); - cie->ias.DAPP(); - if (cie->ias.VerifyPUK(Pin)!=0x9000) - throw p11_error(CKR_PIN_INCORRECT); - - if(cie->ias.UnblockPIN()!=0x9000) - throw p11_error(CKR_GENERAL_ERROR); - - ByteDynArray changePIN; - cie->ias.GetFirstPIN(changePIN); - changePIN.append(baPin); - - if (cie->ias.ChangePIN(changePIN)!=0x9000) - throw p11_error(CKR_GENERAL_ERROR); - } - } else - throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); -} - -void CIEtemplateSetPIN(void *pCardTemplateData, ByteArray &baOldPin, ByteArray &baNewPin, CK_USER_TYPE User) { - init_func - CToken token; - CIEData* cie = (CIEData*)pCardTemplateData; - if (cie->userType != CKU_SO) { - // posso usarla sia se sono loggato come user sia se non sono loggato - ByteDynArray Pin; - cie->slot.Connect(); - cie->ias.SetCardContext(&cie->slot); - cie->ias.token.Reset(); - { - safeConnection safeConn(cie->slot.hCard); - CCardLocker lockCard(cie->slot.hCard); - cie->ias.SelectAID_IAS(); - if (cie->userType != CKU_USER) - cie->ias.InitDHParam(); - cie->ias.SelectAID_CIE(); - - if (cie->userType != CKU_USER) { - cie->ias.ReadPAN(); - ByteDynArray resp; - cie->ias.ReadDappPubKey(resp); - } - - cie->ias.DHKeyExchange(); - cie->ias.DAPP(); - ByteDynArray oldPIN, newPIN; - cie->ias.GetFirstPIN(oldPIN); - newPIN = oldPIN; - oldPIN.append(baOldPin); - newPIN.append(baNewPin); - - if (cie->ias.VerifyPIN(oldPIN) != 0x9000) - throw p11_error(CKR_PIN_INCORRECT); - if (cie->ias.ChangePIN(oldPIN, newPIN) != 0x9000) - throw p11_error(CKR_GENERAL_ERROR); - } - } else - throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); -} - -void CIEtemplateSignRecover(void *pCardTemplateData, CP11PrivateKey *pPrivKey, ByteArray &baSignBuffer, ByteDynArray &baSignature, CK_MECHANISM_TYPE mechanism, bool bSilent) { - throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); -} -void CIEtemplateDecrypt(void *pCardTemplateData, CP11PrivateKey *pPrivKey, ByteArray &baEncryptedData, ByteDynArray &baData, CK_MECHANISM_TYPE mechanism, bool bSilent) { - throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); -} -void CIEtemplateGenerateRandom(void *pCardTemplateData, ByteArray &baRandomData) { - throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); -} -CK_ULONG CIEtemplateGetObjectSize(void *pCardTemplateData, CP11Object *pObject) { - throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); -} -void CIEtemplateSetKeyPIN(void *pTemplateData, CP11Object *pObject, ByteArray &Pin) { - throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); -} -void CIEtemplateSetAttribute(void *pTemplateData, CP11Object *pObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { - throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); -} -std::shared_ptr CIEtemplateCreateObject(void *pTemplateData, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { - throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); -} -void CIEtemplateDestroyObject(void *pTemplateData, CP11Object &Object) { - throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); -} -std::shared_ptr CIEtemplateGenerateKey(void *pCardTemplateData, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { - throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); -} -void CIEtemplateGenerateKeyPair(void *pCardTemplateData, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount, std::shared_ptr&pPublicKey, std::shared_ptr&pPrivateKey) { - throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); -} - - -/** - * Reads an X.509 v3 certificate from certin, extracts the subjectPublicKeyInfo structure - * (which is one way PK_Verifiers can get their key material) and writes it to keyout - * - * @throws CryptoPP::BERDecodeError - */ - -void GetPublicKeyFromCert(CryptoPP::BufferedTransformation & certin, - CryptoPP::BufferedTransformation & keyout, - CryptoPP::BufferedTransformation & issuer, - - Integer &serial) { - BERSequenceDecoder x509Cert(certin); - BERSequenceDecoder tbsCert(x509Cert); - - // ASN.1 from RFC 3280 - // TBSCertificate ::= SEQUENCE { - // version [0] EXPLICIT Version DEFAULT v1, - - // consume the context tag on the version - BERGeneralDecoder context(tbsCert,0xa0); - word32 ver; - - // only want a v3 cert - BERDecodeUnsigned(context,ver,INTEGER,2,2); - - // serialNumber CertificateSerialNumber, - serial.BERDecode(tbsCert); - - // signature AlgorithmIdentifier, - BERSequenceDecoder signature(tbsCert); - signature.SkipAll(); - - // issuer Name, - BERSequenceDecoder issuerName(tbsCert); - issuerName.CopyTo(issuer); - issuerName.SkipAll(); - - // validity Validity, - BERSequenceDecoder validity(tbsCert); - validity.SkipAll(); - - // subject Name, - BERSequenceDecoder subjectName(tbsCert); - subjectName.SkipAll(); - - // subjectPublicKeyInfo SubjectPublicKeyInfo, - BERSequenceDecoder spki(tbsCert); - DERSequenceEncoder spkiEncoder(keyout); - - spki.CopyTo(spkiEncoder); - spkiEncoder.MessageEnd(); - - spki.SkipAll(); - tbsCert.SkipAll(); - x509Cert.SkipAll(); -} - - - -void GetCertInfo(CryptoPP::BufferedTransformation & certin, - std::string & serial, - CryptoPP::BufferedTransformation & issuer, - CryptoPP::BufferedTransformation & subject, - std::string & notBefore, - std::string & notAfter, - CryptoPP::Integer& mod, - CryptoPP::Integer& pubExp) { - - BERSequenceDecoder cert(certin); - - BERSequenceDecoder toBeSignedCert(cert); - - // consume the context tag on the version - BERGeneralDecoder context(toBeSignedCert,0xa0); - word32 ver; - - // only want a v3 cert - BERDecodeUnsigned(context,ver,INTEGER,2,2); - - serial = CryptoppUtils::Cert::ReadIntegerAsString(toBeSignedCert); - - // algorithmId - CryptoppUtils::Cert::SkipNextSequence(toBeSignedCert); - - - // issuer Name, - BERSequenceDecoder issuerName(toBeSignedCert); - DERSequenceEncoder issuerEncoder(issuer); - issuerName.CopyTo(issuerEncoder); - issuerEncoder.MessageEnd(); - -// issuerName.CopyTo(issuer); - issuerName.SkipAll(); - -// CryptoPP::BERSequenceDecoder issuer(toBeSignedCert); { -// CryptoPP::BERSetDecoder c(issuer); -// c.SkipAll(); -// CryptoPP::BERSetDecoder st(issuer); -// st.SkipAll(); -// CryptoPP::BERSetDecoder l(issuer); -// l.SkipAll(); -// CryptoPP::BERSetDecoder o(issuer); -// o.SkipAll(); -// CryptoPP::BERSetDecoder ou(issuer); -// ou.SkipAll(); -// CryptoPP::BERSetDecoder cn(issuer); { -// CryptoPP::BERSequenceDecoder attributes(cn); { -// CryptoPP::BERGeneralDecoder ident( -// attributes, -// CryptoPP::OBJECT_IDENTIFIER); -// ident.SkipAll(); -// CryptoPP::BERDecodeTextString( -// attributes, -// issuerCN, -// CryptoPP::UTF8_STRING); -// } -// } -// } -// -// issuer.SkipAll(); - - // validity - CryptoppUtils::Cert::ReadDateTimeSequence(toBeSignedCert, notBefore, notAfter); - - // subject - BERSequenceDecoder subjectName(toBeSignedCert); - DERSequenceEncoder subjectEncoder(subject); - subjectName.CopyTo(subjectEncoder); - subjectEncoder.MessageEnd(); - -// subjectName.CopyTo(subject); - subjectName.SkipAll(); -// -// CryptoPP::BERSequenceDecoder subject(toBeSignedCert); { -// CryptoPP::BERSetDecoder c(subject); -// c.SkipAll(); -// CryptoPP::BERSetDecoder st(subject); -// st.SkipAll(); -// CryptoPP::BERSetDecoder l(subject); -// l.SkipAll(); -// CryptoPP::BERSetDecoder o(subject); -// o.SkipAll(); -// CryptoPP::BERSetDecoder ou(subject); -// ou.SkipAll(); -// CryptoPP::BERSetDecoder cn(subject); { -// CryptoPP::BERSequenceDecoder attributes(cn); { -// CryptoPP::BERGeneralDecoder ident( -// attributes, -// CryptoPP::OBJECT_IDENTIFIER); -// ident.SkipAll(); -// CryptoPP::BERDecodeTextString( -// attributes, -// subjectCN, -// CryptoPP::UTF8_STRING); -// } -// -// subject.SkipAll(); -// } -// } - - // Public key - CryptoPP::BERSequenceDecoder publicKey(toBeSignedCert); - { - CryptoPP::BERSequenceDecoder ident(publicKey); - ident.SkipAll(); - CryptoPP::BERGeneralDecoder key(publicKey, CryptoPP::BIT_STRING); - key.Skip(1); // Must skip (possibly a bug in Crypto++) - CryptoPP::BERSequenceDecoder keyPair(key); - - mod.BERDecode(keyPair); - pubExp.BERDecode(keyPair); - - - } - - publicKey.SkipAll(); - toBeSignedCert.SkipAll(); - cert.SkipAll(); -} - - + +#include "CIEP11Template.h" +#include "../CSP/IAS.h" +#include "../PCSC/CardLocker.h" +#include "../Crypto/ASNParser.h" +#include "../Crypto/AES.h" +#include "../PCSC/PCSC.h" +#include +#include +#include "../Util/CryptoppUtils.h" +#include +extern CLog Log; + +#include "../LOGGER/Logger.h" + +using namespace CryptoPP; +using namespace lcp; +using namespace CieIDLogger; + +void notifyPINLocked(); +void notifyPINWrong(int trials); + +void GetCertInfo(CryptoPP::BufferedTransformation & certin, + std::string & serial, + CryptoPP::BufferedTransformation & issuer, + CryptoPP::BufferedTransformation & subject, + std::string & notBefore, + std::string & notAfter, + CryptoPP::Integer& mod, + CryptoPP::Integer& pubExp); + +int TokenTransmitCallback(CSlot *data, BYTE *apdu, DWORD apduSize, BYTE *resp, DWORD *respSize) { + if (apduSize == 2) { + WORD code = *(WORD*)apdu; + if (code == 0xfffd) { + long bufLen = *respSize; + *respSize = sizeof(data->hCard)+2; + CryptoPP::memcpy_s(resp, bufLen, &data->hCard, sizeof(data->hCard)); + resp[sizeof(data->hCard)] = 0; + resp[sizeof(data->hCard) + 1] = 0; + + return SCARD_S_SUCCESS; + } else if (code == 0xfffe) { + DWORD protocol = 0; + ODS("UNPOWER CARD"); + auto ris = SCardReconnect(data->hCard, SCARD_SHARE_SHARED, SCARD_PROTOCOL_Tx, SCARD_UNPOWER_CARD, &protocol); + + + if (ris == SCARD_S_SUCCESS) { + SCardBeginTransaction(data->hCard); + *respSize = 2; + resp[0] = 0x90; + resp[1] = 0x00; + } + return ris; + } else if (code == 0xffff) { + DWORD protocol = 0; + auto ris = SCardReconnect(data->hCard, SCARD_SHARE_SHARED, SCARD_PROTOCOL_Tx, SCARD_RESET_CARD, &protocol); + if (ris == SCARD_S_SUCCESS) { + SCardBeginTransaction(data->hCard); + *respSize = 2; + resp[0] = 0x90; + resp[1] = 0x00; + } + ODS("RESET CARD"); + return ris; + } + } + + //Log.writePure("APDU: %s", dumpHexData(ByteArray(apdu, apduSize)).c_str()); + + //ODS(String().printf("APDU: %s\n", dumpHexData(ByteArray(apdu, apduSize), String()).lock()).lock()); + auto ris = SCardTransmit(data->hCard, SCARD_PCI_T1, apdu, apduSize, NULL, resp, respSize); + if(ris == SCARD_W_RESET_CARD || ris == SCARD_W_UNPOWERED_CARD) { + LOG_ERROR("TokenTransmitCallback - Card reset error: %x", ris); + + DWORD protocol = 0; + ris = SCardReconnect(data->hCard, SCARD_SHARE_SHARED, SCARD_PROTOCOL_Tx, SCARD_LEAVE_CARD, &protocol); + if (ris != SCARD_S_SUCCESS) { + LOG_ERROR("TokenTransmitCallback - Errore reconnect %d", ris); + } else + ris = SCardTransmit(data->hCard, SCARD_PCI_T1, apdu, apduSize, NULL, resp, respSize); + } + + if (ris != SCARD_S_SUCCESS) { + LOG_ERROR("TokenTransmitCallback - APDU transmission error: %x", ris); + } + //else + //ODS(String().printf("RESP: %s\n", dumpHexData(ByteArray(resp, *respSize), String()).lock()).lock()); + + return ris; +} + +class CIEData { + public: + CK_USER_TYPE userType; + CAES aesKey; + CToken token; + bool init; + CIEData(CSlot *slot,ByteArray atr) : ias((CToken::TokenTransmitCallback)TokenTransmitCallback,atr), slot(*slot) { + ByteDynArray key(32); + ByteDynArray iv(16); + aesKey.Init(key.random(),iv.random()); + token.setTransmitCallbackData(slot); + userType = -1; + init = false; + } + CSlot &slot; + IAS ias; + std::shared_ptr pubKey; + std::shared_ptr privKey; + std::shared_ptr cert; + ByteDynArray SessionPIN; +}; + +void CIEtemplateInitLibrary(class CCardTemplate &Template, void *templateData) { + return; +} +void CIEtemplateInitCard(void *&pTemplateData, CSlot &pSlot) { + init_func + ByteArray ATR; + pSlot.GetATR(ATR); + + pTemplateData = new CIEData(&pSlot, ATR); +} +void CIEtemplateFinalCard(void *pTemplateData) { + if (pTemplateData) + delete (CIEData*)pTemplateData; +} + +ByteArray SkipZero(ByteArray &ba) { + for (DWORD i = 0; i < ba.size(); i++) { + if (ba[i] != 0) + return ba.mid(i); + } + return ByteArray(); +} + +BYTE label[] = { 'C','I','E','0' }; +void CIEtemplateInitSession(void *pTemplateData) { + CIEData* cie=(CIEData*)pTemplateData; + + if (!cie->init) { + ByteDynArray certRaw; + cie->slot.Connect(); + { + safeConnection faseConn(cie->slot.hCard); + CCardLocker lockCard(cie->slot.hCard); + cie->ias.SetCardContext(&cie->slot); + cie->ias.SelectAID_IAS(); + cie->ias.ReadPAN(); + + ByteDynArray resp; + cie->ias.SelectAID_CIE(); + cie->ias.ReadDappPubKey(resp); + cie->ias.InitEncKey(); + cie->ias.GetCertificate(certRaw, true); + } + + + CK_BBOOL vtrue = TRUE; + CK_BBOOL vfalse = FALSE; + + cie->pubKey = std::make_shared(cie); + cie->privKey = std::make_shared(cie); + cie->cert = std::make_shared(cie); + + cie->pubKey->addAttribute(CKA_LABEL, VarToByteArray(label)); + cie->pubKey->addAttribute(CKA_ID, VarToByteArray(label)); + cie->pubKey->addAttribute(CKA_PRIVATE, VarToByteArray(vfalse)); + cie->pubKey->addAttribute(CKA_TOKEN, VarToByteArray(vtrue)); + cie->pubKey->addAttribute(CKA_VERIFY, VarToByteArray(vtrue)); + CK_KEY_TYPE keyrsa = CKK_RSA; + cie->pubKey->addAttribute(CKA_KEY_TYPE, VarToByteArray(keyrsa)); + + cie->privKey->addAttribute(CKA_LABEL, VarToByteArray(label)); + cie->privKey->addAttribute(CKA_ID, VarToByteArray(label)); + cie->privKey->addAttribute(CKA_PRIVATE, VarToByteArray(vtrue)); + cie->privKey->addAttribute(CKA_TOKEN, VarToByteArray(vtrue)); + cie->privKey->addAttribute(CKA_KEY_TYPE, VarToByteArray(keyrsa)); + + cie->privKey->addAttribute(CKA_SIGN, VarToByteArray(vtrue)); + + cie->cert->addAttribute(CKA_LABEL, VarToByteArray(label)); + cie->cert->addAttribute(CKA_ID, VarToByteArray(label)); + cie->cert->addAttribute(CKA_PRIVATE, VarToByteArray(vfalse)); + cie->cert->addAttribute(CKA_TOKEN, VarToByteArray(vtrue)); + + CK_CERTIFICATE_TYPE certx509 = CKC_X_509; + cie->cert->addAttribute(CKA_CERTIFICATE_TYPE, VarToByteArray(certx509)); + + //LOG_DEBUG("CIEtemplateInitSession - certRaw: %s", dumpHexData(certRaw).c_str()); + +#ifdef WIN32 + PCCERT_CONTEXT certDS = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, certRaw.data(), (DWORD)certRaw.size()); + if (certDS != nullptr) { + auto _1 = scopeExit([&]() noexcept { + CertFreeCertificateContext(certDS); + }); + + + + CASNParser keyParser; + keyParser.Parse(ByteArray(certDS->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData, certDS->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData)); + auto Module = SkipZero(keyParser.tags[0]->tags[0]->content); + auto Exponent = SkipZero(keyParser.tags[0]->tags[1]->content); + CK_LONG keySizeBits = (CK_LONG)Module.size() * 8; + + cie->pubKey->addAttribute(CKA_MODULUS, Module); + cie->pubKey->addAttribute(CKA_PUBLIC_EXPONENT, Exponent); + cie->pubKey->addAttribute(CKA_MODULUS_BITS, VarToByteArray(keySizeBits)); + + + + + cie->privKey->addAttribute(CKA_MODULUS, Module); + cie->privKey->addAttribute(CKA_PUBLIC_EXPONENT, Exponent); + + cie->cert->addAttribute(CKA_ISSUER, ByteArray(certDS->pCertInfo->Issuer.pbData, certDS->pCertInfo->Issuer.cbData)); + cie->cert->addAttribute(CKA_SERIAL_NUMBER, ByteArray(certDS->pCertInfo->SerialNumber.pbData, certDS->pCertInfo->SerialNumber.cbData)); + cie->cert->addAttribute(CKA_SUBJECT, ByteArray(certDS->pCertInfo->Subject.pbData, certDS->pCertInfo->Subject.cbData)); + + CK_DATE start, end; + SYSTEMTIME sFrom, sTo; + char temp[10]; + if (!FileTimeToSystemTime(&certDS->pCertInfo->NotBefore, &sFrom)) + throw logged_error("Errore nella data di inizio validita' certificato"); + if (!FileTimeToSystemTime(&certDS->pCertInfo->NotAfter, &sTo)) + throw logged_error("Errore nella data di fine validita' certificato"); + snprintf_s(temp, 10, "%04i", sFrom.wYear); + VarToByteArray(start.year).copy(ByteArray((BYTE*)temp, 4)); + snprintf_s(temp, 10, "%02i", sFrom.wMonth); + VarToByteArray(start.month).copy(ByteArray((BYTE*)temp, 2)); + snprintf_s(temp, 10, "%02i", sFrom.wDay); + VarToByteArray(start.day).copy(ByteArray((BYTE*)temp, 2)); + snprintf_s(temp, 10, "%04i", sTo.wYear); + VarToByteArray(end.year).copy(ByteArray((BYTE*)temp, 2)); + snprintf_s(temp, 10, "%02i", sTo.wMonth); + VarToByteArray(end.month).copy(ByteArray((BYTE*)temp, 2)); + snprintf_s(temp, 10, "%02i", sTo.wDay); + VarToByteArray(end.day).copy(ByteArray((BYTE*)temp, 2)); + cie->cert->addAttribute(CKA_START_DATE, VarToByteArray(start)); + cie->cert->addAttribute(CKA_END_DATE, VarToByteArray(end)); + } +#else + // TODO decode the certificate + + // not before + // not after + // modulus + // public exponent + // issuer + // serialnumber + // subject + + CryptoPP::ByteQueue certin; + certin.Put(certRaw.data(),certRaw.size()); + + + + std::string serial; + CryptoPP::ByteQueue issuer; + CryptoPP::ByteQueue subject; + std::string notBefore; + std::string notAfter; + CryptoPP::Integer mod; + CryptoPP::Integer pubExp; + + GetCertInfo(certin, serial, issuer, subject, notBefore, notAfter, mod, pubExp); + + ByteDynArray modulus(mod.ByteCount()); + mod.Encode(modulus.data(), modulus.size()); + + ByteDynArray publicExponent(pubExp.ByteCount()); + pubExp.Encode(publicExponent.data(), publicExponent.size()); + + CK_LONG keySizeBits = (CK_LONG)modulus.size() * 8; + + cie->pubKey->addAttribute(CKA_MODULUS, modulus); + cie->pubKey->addAttribute(CKA_PUBLIC_EXPONENT, publicExponent); + cie->pubKey->addAttribute(CKA_MODULUS_BITS, VarToByteArray(keySizeBits)); + + cie->privKey->addAttribute(CKA_MODULUS, modulus); + cie->privKey->addAttribute(CKA_PUBLIC_EXPONENT, publicExponent); + + ByteDynArray issuerBa(issuer.CurrentSize()); + issuer.Get(issuerBa.data(), issuerBa.size()); + + ByteDynArray subjectBa(subject.CurrentSize()); + subject.Get(subjectBa.data(), subjectBa.size()); + + cie->cert->addAttribute(CKA_ISSUER, issuerBa); + cie->cert->addAttribute(CKA_SERIAL_NUMBER, ByteArray((BYTE*)serial.c_str(), serial.size())); + cie->cert->addAttribute(CKA_SUBJECT, subjectBa); + + + CK_DATE start, end; + + SYSTEMTIME sFrom, sTo; + sFrom = convertStringToSystemTime(notBefore.c_str()); + sTo = convertStringToSystemTime(notAfter.c_str()); + + cie->cert->addAttribute(CKA_START_DATE, VarToByteArray(start)); + cie->cert->addAttribute(CKA_END_DATE, VarToByteArray(end)); + + // add to the object +#endif + + size_t len = GetASN1DataLenght(certRaw); + cie->cert->addAttribute(CKA_VALUE, certRaw.left(len)); + + cie->slot.AddP11Object(cie->pubKey); + cie->slot.AddP11Object(cie->privKey); + cie->slot.AddP11Object(cie->cert); + + cie->init = true; + } +} +void CIEtemplateFinalSession(void *pTemplateData) { + //delete (CIEData*)pTemplateData; +} + +bool CIEtemplateMatchCard(CSlot &pSlot) { + init_func + CToken token; + + pSlot.Connect(); + { + safeConnection faseConn(pSlot.hCard); + ByteArray ATR; + pSlot.GetATR(ATR); + token.setTransmitCallback((CToken::TokenTransmitCallback)TokenTransmitCallback, &pSlot); + IAS ias((CToken::TokenTransmitCallback)TokenTransmitCallback, ATR); + ias.SetCardContext(&pSlot); + { + safeTransaction trans(faseConn,SCARD_LEAVE_CARD); + ias.SelectAID_IAS(); + ias.ReadPAN(); + } + return true; + } +} + +ByteDynArray CIEtemplateGetSerial(CSlot &pSlot) { + init_func + CToken token; + + pSlot.Connect(); + { + safeConnection faseConn(pSlot.hCard); + CCardLocker lockCard(pSlot.hCard); + ByteArray ATR; + pSlot.GetATR(ATR); + IAS ias((CToken::TokenTransmitCallback)TokenTransmitCallback, ATR); + ias.SetCardContext(&pSlot); + ias.SelectAID_IAS(); + ias.ReadPAN(); + std::string numSerial; + dumpHexData(ias.PAN.mid(5, 6), numSerial, false); + return ByteArray((BYTE*)numSerial.c_str(),numSerial.length()); + } +} +void CIEtemplateGetModel(CSlot &pSlot, std::string &szModel) { + szModel = ""; +} +void CIEtemplateGetTokenFlags(CSlot &pSlot, CK_FLAGS &dwFlags) { + dwFlags = CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED | CKF_TOKEN_INITIALIZED | CKF_REMOVABLE_DEVICE; +} + +void CIEtemplateLogin(void *pTemplateData, CK_USER_TYPE userType, ByteArray &Pin) { + init_func + CToken token; + CIEData* cie = (CIEData*)pTemplateData; + + cie->SessionPIN.clear(); + cie->userType = -1; + + cie->slot.Connect(); + cie->ias.SetCardContext(&cie->slot); + cie->ias.token.Reset(); + { + safeConnection safeConn(cie->slot.hCard); + CCardLocker lockCard(cie->slot.hCard); + + cie->ias.SelectAID_IAS(); + cie->ias.SelectAID_CIE(); + cie->ias.InitDHParam(); + + if (cie->ias.DappPubKey.isEmpty()) { + ByteDynArray DappKey; + cie->ias.ReadDappPubKey(DappKey); + } + + cie->ias.InitExtAuthKeyParam(); + // faccio lo scambio di chiavi DH + if (cie->ias.Callback != nullptr) + cie->ias.Callback(1, "DiffieHellman", cie->ias.CallbackData); + cie->ias.DHKeyExchange(); + // DAPP + if (cie->ias.Callback != nullptr) + cie->ias.Callback(2, "DAPP", cie->ias.CallbackData); + cie->ias.DAPP(); + // verifica PIN + StatusWord sw; + if (cie->ias.Callback != nullptr) + cie->ias.Callback(3, "Verify PIN", cie->ias.CallbackData); + if (userType == CKU_USER) { + ByteDynArray FullPIN; + cie->ias.GetFirstPIN(FullPIN); + FullPIN.append(Pin); + sw = cie->ias.VerifyPIN(FullPIN); + } else if (userType == CKU_SO) { + sw = cie->ias.VerifyPUK(Pin); + } else + throw p11_error(CKR_ARGUMENTS_BAD); + + if (sw == 0x6983) { + if (userType == CKU_USER) { + notifyPINLocked(); + //cie->ias.IconaSbloccoPIN(); + throw p11_error(CKR_PIN_LOCKED); + } + } + if (sw >= 0x63C0 && sw <= 0x63CF) { + int attemptsRemaining = sw - 0x63C0; + notifyPINWrong(attemptsRemaining); + throw p11_error(CKR_PIN_INCORRECT); + } + if (sw == 0x6700) { + notifyPINWrong(-1); + throw p11_error(CKR_PIN_INCORRECT); + } + if (sw == 0x6300) { + notifyPINWrong(-1); + throw p11_error(CKR_PIN_INCORRECT); + } + if (sw != 0x9000) { + throw scard_error(sw); + } + + cie->SessionPIN = cie->aesKey.Encode(Pin); + cie->userType = userType; + } +} +void CIEtemplateLogout(void *pTemplateData, CK_USER_TYPE userType) { + CIEData* cie = (CIEData*)pTemplateData; + cie->userType = -1; + cie->SessionPIN.clear(); +} +void CIEtemplateReadObjectAttributes(void *pCardTemplateData, CP11Object *pObject) { +} +void CIEtemplateSign(void *pCardTemplateData, CP11PrivateKey *pPrivKey, ByteArray &baSignBuffer, ByteDynArray &baSignature, CK_MECHANISM_TYPE mechanism, bool bSilent) { + init_func + CToken token; + CIEData* cie = (CIEData*)pCardTemplateData; + if (cie->userType == CKU_USER) { + ByteDynArray Pin; + cie->slot.Connect(); + cie->ias.SetCardContext(&cie->slot); + cie->ias.token.Reset(); + { + safeConnection safeConn(cie->slot.hCard); + CCardLocker lockCard(cie->slot.hCard); + + Pin = cie->aesKey.Decode(cie->SessionPIN); + cie->ias.SelectAID_IAS(); + cie->ias.SelectAID_CIE(); + cie->ias.DHKeyExchange(); + cie->ias.DAPP(); + + ByteDynArray FullPIN; + cie->ias.GetFirstPIN(FullPIN); + FullPIN.append(Pin); + if (cie->ias.VerifyPIN(FullPIN) != 0x9000) + throw p11_error(CKR_PIN_INCORRECT); + cie->ias.Sign(baSignBuffer, baSignature); + } + } +} + +void CIEtemplateInitPIN(void *pCardTemplateData, ByteArray &baPin) { + init_func + CToken token; + CIEData* cie = (CIEData*)pCardTemplateData; + if (cie->userType == CKU_SO) { + // posso usarla solo se sono loggato come so + ByteDynArray Pin; + cie->slot.Connect(); + cie->ias.SetCardContext(&cie->slot); + cie->ias.token.Reset(); + { + safeConnection safeConn(cie->slot.hCard); + CCardLocker lockCard(cie->slot.hCard); + + Pin = cie->aesKey.Decode(cie->SessionPIN); + cie->ias.SelectAID_IAS(); + cie->ias.SelectAID_CIE(); + + cie->ias.DHKeyExchange(); + cie->ias.DAPP(); + if (cie->ias.VerifyPUK(Pin)!=0x9000) + throw p11_error(CKR_PIN_INCORRECT); + + if(cie->ias.UnblockPIN()!=0x9000) + throw p11_error(CKR_GENERAL_ERROR); + + ByteDynArray changePIN; + cie->ias.GetFirstPIN(changePIN); + changePIN.append(baPin); + + if (cie->ias.ChangePIN(changePIN)!=0x9000) + throw p11_error(CKR_GENERAL_ERROR); + } + } else + throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); +} + +void CIEtemplateSetPIN(void *pCardTemplateData, ByteArray &baOldPin, ByteArray &baNewPin, CK_USER_TYPE User) { + init_func + CToken token; + CIEData* cie = (CIEData*)pCardTemplateData; + if (cie->userType != CKU_SO) { + // posso usarla sia se sono loggato come user sia se non sono loggato + ByteDynArray Pin; + cie->slot.Connect(); + cie->ias.SetCardContext(&cie->slot); + cie->ias.token.Reset(); + { + safeConnection safeConn(cie->slot.hCard); + CCardLocker lockCard(cie->slot.hCard); + cie->ias.SelectAID_IAS(); + if (cie->userType != CKU_USER) + cie->ias.InitDHParam(); + cie->ias.SelectAID_CIE(); + + if (cie->userType != CKU_USER) { + cie->ias.ReadPAN(); + ByteDynArray resp; + cie->ias.ReadDappPubKey(resp); + } + + cie->ias.DHKeyExchange(); + cie->ias.DAPP(); + ByteDynArray oldPIN, newPIN; + cie->ias.GetFirstPIN(oldPIN); + newPIN = oldPIN; + oldPIN.append(baOldPin); + newPIN.append(baNewPin); + + if (cie->ias.VerifyPIN(oldPIN) != 0x9000) + throw p11_error(CKR_PIN_INCORRECT); + if (cie->ias.ChangePIN(oldPIN, newPIN) != 0x9000) + throw p11_error(CKR_GENERAL_ERROR); + } + } else + throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); +} + +void CIEtemplateSignRecover(void *pCardTemplateData, CP11PrivateKey *pPrivKey, ByteArray &baSignBuffer, ByteDynArray &baSignature, CK_MECHANISM_TYPE mechanism, bool bSilent) { + throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); +} +void CIEtemplateDecrypt(void *pCardTemplateData, CP11PrivateKey *pPrivKey, ByteArray &baEncryptedData, ByteDynArray &baData, CK_MECHANISM_TYPE mechanism, bool bSilent) { + throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); +} +void CIEtemplateGenerateRandom(void *pCardTemplateData, ByteArray &baRandomData) { + throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); +} +CK_ULONG CIEtemplateGetObjectSize(void *pCardTemplateData, CP11Object *pObject) { + throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); +} +void CIEtemplateSetKeyPIN(void *pTemplateData, CP11Object *pObject, ByteArray &Pin) { + throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); +} +void CIEtemplateSetAttribute(void *pTemplateData, CP11Object *pObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { + throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); +} +std::shared_ptr CIEtemplateCreateObject(void *pTemplateData, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { + throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); +} +void CIEtemplateDestroyObject(void *pTemplateData, CP11Object &Object) { + throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); +} +std::shared_ptr CIEtemplateGenerateKey(void *pCardTemplateData, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { + throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); +} +void CIEtemplateGenerateKeyPair(void *pCardTemplateData, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount, std::shared_ptr&pPublicKey, std::shared_ptr&pPrivateKey) { + throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); +} + + +/** + * Reads an X.509 v3 certificate from certin, extracts the subjectPublicKeyInfo structure + * (which is one way PK_Verifiers can get their key material) and writes it to keyout + * + * @throws CryptoPP::BERDecodeError + */ + +void GetPublicKeyFromCert(CryptoPP::BufferedTransformation & certin, + CryptoPP::BufferedTransformation & keyout, + CryptoPP::BufferedTransformation & issuer, + + Integer &serial) { + BERSequenceDecoder x509Cert(certin); + BERSequenceDecoder tbsCert(x509Cert); + + // ASN.1 from RFC 3280 + // TBSCertificate ::= SEQUENCE { + // version [0] EXPLICIT Version DEFAULT v1, + + // consume the context tag on the version + BERGeneralDecoder context(tbsCert,0xa0); + word32 ver; + + // only want a v3 cert + BERDecodeUnsigned(context,ver,INTEGER,2,2); + + // serialNumber CertificateSerialNumber, + serial.BERDecode(tbsCert); + + // signature AlgorithmIdentifier, + BERSequenceDecoder signature(tbsCert); + signature.SkipAll(); + + // issuer Name, + BERSequenceDecoder issuerName(tbsCert); + issuerName.CopyTo(issuer); + issuerName.SkipAll(); + + // validity Validity, + BERSequenceDecoder validity(tbsCert); + validity.SkipAll(); + + // subject Name, + BERSequenceDecoder subjectName(tbsCert); + subjectName.SkipAll(); + + // subjectPublicKeyInfo SubjectPublicKeyInfo, + BERSequenceDecoder spki(tbsCert); + DERSequenceEncoder spkiEncoder(keyout); + + spki.CopyTo(spkiEncoder); + spkiEncoder.MessageEnd(); + + spki.SkipAll(); + tbsCert.SkipAll(); + x509Cert.SkipAll(); +} + + + +void GetCertInfo(CryptoPP::BufferedTransformation & certin, + std::string & serial, + CryptoPP::BufferedTransformation & issuer, + CryptoPP::BufferedTransformation & subject, + std::string & notBefore, + std::string & notAfter, + CryptoPP::Integer& mod, + CryptoPP::Integer& pubExp) { + + BERSequenceDecoder cert(certin); + + BERSequenceDecoder toBeSignedCert(cert); + + // consume the context tag on the version + BERGeneralDecoder context(toBeSignedCert,0xa0); + word32 ver; + + // only want a v3 cert + BERDecodeUnsigned(context,ver,INTEGER,2,2); + + serial = CryptoppUtils::Cert::ReadIntegerAsString(toBeSignedCert); + + // algorithmId + CryptoppUtils::Cert::SkipNextSequence(toBeSignedCert); + + + // issuer Name, + BERSequenceDecoder issuerName(toBeSignedCert); + DERSequenceEncoder issuerEncoder(issuer); + issuerName.CopyTo(issuerEncoder); + issuerEncoder.MessageEnd(); + +// issuerName.CopyTo(issuer); + issuerName.SkipAll(); + +// CryptoPP::BERSequenceDecoder issuer(toBeSignedCert); { +// CryptoPP::BERSetDecoder c(issuer); +// c.SkipAll(); +// CryptoPP::BERSetDecoder st(issuer); +// st.SkipAll(); +// CryptoPP::BERSetDecoder l(issuer); +// l.SkipAll(); +// CryptoPP::BERSetDecoder o(issuer); +// o.SkipAll(); +// CryptoPP::BERSetDecoder ou(issuer); +// ou.SkipAll(); +// CryptoPP::BERSetDecoder cn(issuer); { +// CryptoPP::BERSequenceDecoder attributes(cn); { +// CryptoPP::BERGeneralDecoder ident( +// attributes, +// CryptoPP::OBJECT_IDENTIFIER); +// ident.SkipAll(); +// CryptoPP::BERDecodeTextString( +// attributes, +// issuerCN, +// CryptoPP::UTF8_STRING); +// } +// } +// } +// +// issuer.SkipAll(); + + // validity + CryptoppUtils::Cert::ReadDateTimeSequence(toBeSignedCert, notBefore, notAfter); + + // subject + BERSequenceDecoder subjectName(toBeSignedCert); + DERSequenceEncoder subjectEncoder(subject); + subjectName.CopyTo(subjectEncoder); + subjectEncoder.MessageEnd(); + +// subjectName.CopyTo(subject); + subjectName.SkipAll(); +// +// CryptoPP::BERSequenceDecoder subject(toBeSignedCert); { +// CryptoPP::BERSetDecoder c(subject); +// c.SkipAll(); +// CryptoPP::BERSetDecoder st(subject); +// st.SkipAll(); +// CryptoPP::BERSetDecoder l(subject); +// l.SkipAll(); +// CryptoPP::BERSetDecoder o(subject); +// o.SkipAll(); +// CryptoPP::BERSetDecoder ou(subject); +// ou.SkipAll(); +// CryptoPP::BERSetDecoder cn(subject); { +// CryptoPP::BERSequenceDecoder attributes(cn); { +// CryptoPP::BERGeneralDecoder ident( +// attributes, +// CryptoPP::OBJECT_IDENTIFIER); +// ident.SkipAll(); +// CryptoPP::BERDecodeTextString( +// attributes, +// subjectCN, +// CryptoPP::UTF8_STRING); +// } +// +// subject.SkipAll(); +// } +// } + + // Public key + CryptoPP::BERSequenceDecoder publicKey(toBeSignedCert); + { + CryptoPP::BERSequenceDecoder ident(publicKey); + ident.SkipAll(); + CryptoPP::BERGeneralDecoder key(publicKey, CryptoPP::BIT_STRING); + key.Skip(1); // Must skip (possibly a bug in Crypto++) + CryptoPP::BERSequenceDecoder keyPair(key); + + mod.BERDecode(keyPair); + pubExp.BERDecode(keyPair); + + + } + + publicKey.SkipAll(); + toBeSignedCert.SkipAll(); + cert.SkipAll(); +} + + diff --git a/libcie-pkcs11/PKCS11/CardContext.cpp b/libcie-pkcs11/PKCS11/CardContext.cpp index d04b0fab..2376f38f 100644 --- a/libcie-pkcs11/PKCS11/CardContext.cpp +++ b/libcie-pkcs11/PKCS11/CardContext.cpp @@ -1,68 +1,68 @@ -#include "wintypes.h" -#include "../Util/util.h" -#include "CardContext.h" - -extern CLog Log; - -void CCardContext::getContext() { - init_func -#ifdef WIN32 - HANDLE hSCardSystemEvent=SCardAccessStartedEvent(); - if (hSCardSystemEvent) { - WaitForSingleObject(hSCardSystemEvent,INFINITE); - SCardReleaseStartedEvent(); - } -#endif - - LONG _call_ris; - if ((_call_ris=(SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&hContext)))!=S_OK) { - throw windows_error(_call_ris); - } -} - -CCardContext::CCardContext(void) { - hContext=NULL; - getContext(); -} - -CCardContext::~CCardContext(void) { - if (hContext) - SCardReleaseContext(hContext); -} - -CCardContext::operator SCARDCONTEXT() { - return hContext; -} - - -void CCardContext::validate() { - -#ifdef WIN32 - HANDLE hSCardSystemEvent=SCardAccessStartedEvent(); - if (hSCardSystemEvent) { - WaitForSingleObject(hSCardSystemEvent,INFINITE); - SCardReleaseStartedEvent(); - } -#endif - - if (hContext) - if (SCardIsValidContext(hContext)!=SCARD_S_SUCCESS) - hContext = NULL; - - if (hContext == 0) { - getContext(); - } -} - -void CCardContext::renew() { - init_func - - LONG ris; - if (hContext) - if ((ris=SCardReleaseContext(hContext)) != SCARD_S_SUCCESS) - throw windows_error(ris); - hContext=NULL; - - getContext(); - -} +#include "wintypes.h" +#include "../Util/util.h" +#include "CardContext.h" + +extern CLog Log; + +void CCardContext::getContext() { + init_func +#ifdef WIN32 + HANDLE hSCardSystemEvent=SCardAccessStartedEvent(); + if (hSCardSystemEvent) { + WaitForSingleObject(hSCardSystemEvent,INFINITE); + SCardReleaseStartedEvent(); + } +#endif + + LONG _call_ris; + if ((_call_ris=(SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&hContext)))!=S_OK) { + throw windows_error(_call_ris); + } +} + +CCardContext::CCardContext(void) { + hContext=NULL; + getContext(); +} + +CCardContext::~CCardContext(void) { + if (hContext) + SCardReleaseContext(hContext); +} + +CCardContext::operator SCARDCONTEXT() { + return hContext; +} + + +void CCardContext::validate() { + +#ifdef WIN32 + HANDLE hSCardSystemEvent=SCardAccessStartedEvent(); + if (hSCardSystemEvent) { + WaitForSingleObject(hSCardSystemEvent,INFINITE); + SCardReleaseStartedEvent(); + } +#endif + + if (hContext) + if (SCardIsValidContext(hContext)!=SCARD_S_SUCCESS) + hContext = NULL; + + if (hContext == 0) { + getContext(); + } +} + +void CCardContext::renew() { + init_func + + LONG ris; + if (hContext) + if ((ris=SCardReleaseContext(hContext)) != SCARD_S_SUCCESS) + throw windows_error(ris); + hContext=NULL; + + getContext(); + +} diff --git a/libcie-pkcs11/PKCS11/CardTemplate.cpp b/libcie-pkcs11/PKCS11/CardTemplate.cpp index c08af143..f16768a4 100644 --- a/libcie-pkcs11/PKCS11/CardTemplate.cpp +++ b/libcie-pkcs11/PKCS11/CardTemplate.cpp @@ -1,124 +1,124 @@ - -#include "CardTemplate.h" -#include "../Util/util.h" -#include "../Util/ModuleInfo.h" -#include "CIEP11Template.h" - -extern CLog Log; - -#ifdef WIN32 -static char *szCompiledFile=__FILE__; - -const char szTemplatesQry[]="./TEMPLATES"; -const char szTemplateNode[]="TEMPLATE"; -const char szLibPathQry[]="./DLLMANAGER"; -const char szNameQry[]="./NAME"; -#endif - -extern CModuleInfo moduleInfo; - -namespace p11 { -#ifdef WIN32 -static const char *szTemplateFuncListName = "TemplateGetFunctionList"; -#endif - -TemplateVector CCardTemplate::g_mCardTemplates; - -CCardTemplate::CCardTemplate(void) { -#ifdef WIN32 - hLibrary=NULL; -#endif -} - -CCardTemplate::~CCardTemplate(void) { -#ifdef WIN32 - if (hLibrary) - FreeLibrary(hLibrary); -#endif -} - -void CCardTemplate::AddTemplate(std::shared_ptr pTemplate) { - init_func - g_mCardTemplates.emplace_back(std::move(pTemplate)); -} - -void CCardTemplate::DeleteTemplateList() { - init_func - g_mCardTemplates.clear(); -} - -void CCardTemplate::InitTemplateList() { - init_func - - auto pTemplate = std::unique_ptr(new CCardTemplate()); - pTemplate->szName = "CIE";// "Carta d'Identità Elettronica"; - pTemplate->szManifacturer = ""; - pTemplate->FunctionList.templateInitLibrary = CIEtemplateInitLibrary; - pTemplate->FunctionList.templateInitCard = CIEtemplateInitCard; - pTemplate->FunctionList.templateFinalCard = CIEtemplateFinalCard; - pTemplate->FunctionList.templateInitSession = CIEtemplateInitSession; - pTemplate->FunctionList.templateFinalSession = CIEtemplateFinalSession; - pTemplate->FunctionList.templateMatchCard = CIEtemplateMatchCard; - pTemplate->FunctionList.templateGetSerial = CIEtemplateGetSerial; - pTemplate->FunctionList.templateGetModel = CIEtemplateGetModel; - pTemplate->FunctionList.templateLogin = CIEtemplateLogin; - pTemplate->FunctionList.templateLogout = CIEtemplateLogout; - pTemplate->FunctionList.templateReadObjectAttributes = CIEtemplateReadObjectAttributes; - pTemplate->FunctionList.templateSign = CIEtemplateSign; - pTemplate->FunctionList.templateSignRecover = CIEtemplateSignRecover; - pTemplate->FunctionList.templateDecrypt = CIEtemplateDecrypt; - pTemplate->FunctionList.templateGenerateRandom = CIEtemplateGenerateRandom; - pTemplate->FunctionList.templateInitPIN = CIEtemplateInitPIN; - pTemplate->FunctionList.templateSetPIN = CIEtemplateSetPIN; - pTemplate->FunctionList.templateGetObjectSize = CIEtemplateGetObjectSize; - pTemplate->FunctionList.templateSetKeyPIN = CIEtemplateSetKeyPIN; - pTemplate->FunctionList.templateSetAttribute = CIEtemplateSetAttribute; - pTemplate->FunctionList.templateCreateObject = CIEtemplateCreateObject; - pTemplate->FunctionList.templateDestroyObject = CIEtemplateDestroyObject; - pTemplate->FunctionList.templateGetTokenFlags = CIEtemplateGetTokenFlags; - pTemplate->FunctionList.templateGenerateKey = CIEtemplateGenerateKey; - pTemplate->FunctionList.templateGenerateKeyPair = CIEtemplateGenerateKeyPair; - - AddTemplate(std::move(pTemplate)); -} - -std::shared_ptr CCardTemplate::GetTemplate(CSlot &pSlot) { - init_func - for (DWORD i=0; iFunctionList.templateMatchCard(pSlot)) { - return g_mCardTemplates[i]; - } - } catch(...) { } - } - return nullptr; -} - -//RESULT CCardTemplate::InitLibrary(const char *szPath,void *templateData) -//{ -// init_func -// hLibrary=LoadLibrary(szPath); -// if (hLibrary==NULL) { -// throw CStringException(CWinException(), ERR_CANT_LOAD_LIBRARY); -// } -// -// templateFuncListFunc funcList; -// funcList=(templateFuncListFunc)GetProcAddress(hLibrary,szTemplateFuncListName); -// if (!funcList) { -// throw CStringException(ERR_GET_LIBRARY_FUNCTION_LIST); -// } -// -// if (funcList(&FunctionList)) { -// throw CStringException(ERR_CALL_LIBRARY_FUNCTION_LIST); -// } -// -// if (FunctionList.templateInitLibrary(*this,templateData)) { -// throw CStringException(ERR_INIT_LIBRARY); -// } -// -// _return(OK) -// exit_func -// _return(FAIL) -//} - -}; + +#include "CardTemplate.h" +#include "../Util/util.h" +#include "../Util/ModuleInfo.h" +#include "CIEP11Template.h" + +extern CLog Log; + +#ifdef WIN32 +static char *szCompiledFile=__FILE__; + +const char szTemplatesQry[]="./TEMPLATES"; +const char szTemplateNode[]="TEMPLATE"; +const char szLibPathQry[]="./DLLMANAGER"; +const char szNameQry[]="./NAME"; +#endif + +extern CModuleInfo moduleInfo; + +namespace p11 { +#ifdef WIN32 +static const char *szTemplateFuncListName = "TemplateGetFunctionList"; +#endif + +TemplateVector CCardTemplate::g_mCardTemplates; + +CCardTemplate::CCardTemplate(void) { +#ifdef WIN32 + hLibrary=NULL; +#endif +} + +CCardTemplate::~CCardTemplate(void) { +#ifdef WIN32 + if (hLibrary) + FreeLibrary(hLibrary); +#endif +} + +void CCardTemplate::AddTemplate(std::shared_ptr pTemplate) { + init_func + g_mCardTemplates.emplace_back(std::move(pTemplate)); +} + +void CCardTemplate::DeleteTemplateList() { + init_func + g_mCardTemplates.clear(); +} + +void CCardTemplate::InitTemplateList() { + init_func + + auto pTemplate = std::unique_ptr(new CCardTemplate()); + pTemplate->szName = "CIE";// "Carta d'Identità Elettronica"; + pTemplate->szManifacturer = ""; + pTemplate->FunctionList.templateInitLibrary = CIEtemplateInitLibrary; + pTemplate->FunctionList.templateInitCard = CIEtemplateInitCard; + pTemplate->FunctionList.templateFinalCard = CIEtemplateFinalCard; + pTemplate->FunctionList.templateInitSession = CIEtemplateInitSession; + pTemplate->FunctionList.templateFinalSession = CIEtemplateFinalSession; + pTemplate->FunctionList.templateMatchCard = CIEtemplateMatchCard; + pTemplate->FunctionList.templateGetSerial = CIEtemplateGetSerial; + pTemplate->FunctionList.templateGetModel = CIEtemplateGetModel; + pTemplate->FunctionList.templateLogin = CIEtemplateLogin; + pTemplate->FunctionList.templateLogout = CIEtemplateLogout; + pTemplate->FunctionList.templateReadObjectAttributes = CIEtemplateReadObjectAttributes; + pTemplate->FunctionList.templateSign = CIEtemplateSign; + pTemplate->FunctionList.templateSignRecover = CIEtemplateSignRecover; + pTemplate->FunctionList.templateDecrypt = CIEtemplateDecrypt; + pTemplate->FunctionList.templateGenerateRandom = CIEtemplateGenerateRandom; + pTemplate->FunctionList.templateInitPIN = CIEtemplateInitPIN; + pTemplate->FunctionList.templateSetPIN = CIEtemplateSetPIN; + pTemplate->FunctionList.templateGetObjectSize = CIEtemplateGetObjectSize; + pTemplate->FunctionList.templateSetKeyPIN = CIEtemplateSetKeyPIN; + pTemplate->FunctionList.templateSetAttribute = CIEtemplateSetAttribute; + pTemplate->FunctionList.templateCreateObject = CIEtemplateCreateObject; + pTemplate->FunctionList.templateDestroyObject = CIEtemplateDestroyObject; + pTemplate->FunctionList.templateGetTokenFlags = CIEtemplateGetTokenFlags; + pTemplate->FunctionList.templateGenerateKey = CIEtemplateGenerateKey; + pTemplate->FunctionList.templateGenerateKeyPair = CIEtemplateGenerateKeyPair; + + AddTemplate(std::move(pTemplate)); +} + +std::shared_ptr CCardTemplate::GetTemplate(CSlot &pSlot) { + init_func + for (DWORD i=0; iFunctionList.templateMatchCard(pSlot)) { + return g_mCardTemplates[i]; + } + } catch(...) { } + } + return nullptr; +} + +//RESULT CCardTemplate::InitLibrary(const char *szPath,void *templateData) +//{ +// init_func +// hLibrary=LoadLibrary(szPath); +// if (hLibrary==NULL) { +// throw CStringException(CWinException(), ERR_CANT_LOAD_LIBRARY); +// } +// +// templateFuncListFunc funcList; +// funcList=(templateFuncListFunc)GetProcAddress(hLibrary,szTemplateFuncListName); +// if (!funcList) { +// throw CStringException(ERR_GET_LIBRARY_FUNCTION_LIST); +// } +// +// if (funcList(&FunctionList)) { +// throw CStringException(ERR_CALL_LIBRARY_FUNCTION_LIST); +// } +// +// if (FunctionList.templateInitLibrary(*this,templateData)) { +// throw CStringException(ERR_INIT_LIBRARY); +// } +// +// _return(OK) +// exit_func +// _return(FAIL) +//} + +}; diff --git a/libcie-pkcs11/PKCS11/Mechanism.cpp b/libcie-pkcs11/PKCS11/Mechanism.cpp index c3e99e6c..2c632491 100644 --- a/libcie-pkcs11/PKCS11/Mechanism.cpp +++ b/libcie-pkcs11/PKCS11/Mechanism.cpp @@ -1,981 +1,981 @@ - -#include "Mechanism.h" -#include "../Crypto/RSA.h" -#include "P11Object.h" -#include "../Util/util.h" - -extern CLog Log; - -//static char *szCompiledFile=__FILE__; - -static BYTE SHA1_RSAcode[]= {0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x05,0x00,0x04,0x14}; -static BYTE MD5_RSAcode[]= {0x30,0x20,0x30,0x0C,0x06,0x08,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x05,0x05,0x00,0x04,0x10}; -static ByteArray baSHA1DigestInfo(SHA1_RSAcode,sizeof(SHA1_RSAcode)); -static ByteArray baMD5DigestInfo(MD5_RSAcode,sizeof(MD5_RSAcode)); - -namespace p11 { - -CMechanism::CMechanism(CK_MECHANISM_TYPE type, std::shared_ptr Session) : mtType(type), pSession(std::move(Session)) {} -CMechanism::~CMechanism() {} -/*bool CDecrypt::checkCache(ByteArray &Data, ByteArray &Result) -{ - init_func - if (Data.data() == cacheData.data() && Data.size() == cacheData.size()) { - if (!Result.isNull()) { - if (Result.size() < resultCache.size()) - throw new p11_error(CKR_BUFFER_TOO_SMALL); - - Result.copy(resultCache); - Result = Result.left(resultCache.size()); - return true; - } - } - return false; -} - -void CDecrypt::setCache(ByteArray &Data, ByteArray &Result) -{ - init_func - cacheData = Data; - resultCache = Result; -}*/ - -CVerify::CVerify(CK_MECHANISM_TYPE type, std::shared_ptr Session) : CMechanism(type, std::move(Session)) {} -CVerify::~CVerify() {} - -CVerifyRecover::CVerifyRecover(CK_MECHANISM_TYPE type, std::shared_ptr Session) : CMechanism(type, std::move(Session)) {} -CVerifyRecover::~CVerifyRecover() {} - -CDigest::CDigest(CK_MECHANISM_TYPE type, std::shared_ptr Session) : CMechanism(type, std::move(Session)) {} -CDigest::~CDigest() {} - -CSign::CSign(CK_MECHANISM_TYPE type, std::shared_ptr Session) : CMechanism(type, std::move(Session)) {} -CSign::~CSign() {} - -CSignRecover::CSignRecover(CK_MECHANISM_TYPE type, std::shared_ptr Session) : CMechanism(type, std::move(Session)) {} -CSignRecover::~CSignRecover() {} - -/*CEncrypt::CEncrypt(CK_MECHANISM_TYPE type, std::shared_ptr Session) : CMechanism(type, std::move(Session)) {} -CEncrypt::~CEncrypt() {} - -BYTE CDecrypt::uninitializedCacheData = 0; -CDecrypt::CDecrypt(CK_MECHANISM_TYPE type, std::shared_ptr Session) - : CMechanism(type, Session), cacheData(&uninitializedCacheData, 1) {} -CDecrypt::~CDecrypt() {}*/ - -/* ******************** */ -/* SHA1 */ -/* ******************** */ -CDigestSHA::CDigestSHA(std::shared_ptr Session) : CDigest(CKM_SHA_1, std::move(Session)) {} -CDigestSHA::~CDigestSHA() {} - -void CDigestSHA::DigestInit() { - init_func - data.clear(); -} - -void CDigestSHA::DigestUpdate(ByteArray &Part) { - init_func - data.append(Part); -} - -void CDigestSHA::DigestFinal(ByteArray &Digest) { - init_func - - // data.append(Digest); - ByteDynArray dataOut(SHA_DIGEST_LENGTH); - dataOut = sha1.Digest(data);//, dataOut); - Digest.copy(dataOut); -} - -CK_ULONG CDigestSHA::DigestLength() { - init_func - return SHA_DIGEST_LENGTH; -} - -ByteArray CDigestSHA::DigestInfo() { - init_func - return baSHA1DigestInfo; -} - -ByteDynArray CDigestSHA::DigestGetOperationState() { - init_func - throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); -} - -void CDigestSHA::DigestSetOperationState(ByteArray &OperationState) { - init_func - throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); -} - -/* ******************** */ -/* SHA256 */ -/* ******************** */ -CDigestSHA256::CDigestSHA256(std::shared_ptr Session) : CDigest(CKM_SHA_1, std::move(Session)) {} -CDigestSHA256::~CDigestSHA256() {} - -void CDigestSHA256::DigestInit() { - init_func - data.clear(); -} - -void CDigestSHA256::DigestUpdate(ByteArray &Part) { - init_func - data.append(Part); -} - -void CDigestSHA256::DigestFinal(ByteArray &Digest) { - init_func - - // data.append(Digest); - ByteDynArray dataOut(SHA256_DIGEST_LENGTH); - dataOut = sha256.Digest(data);//, dataOut); - Digest.copy(dataOut); -} - -CK_ULONG CDigestSHA256::DigestLength() { - init_func - return SHA256_DIGEST_LENGTH; -} - -ByteArray CDigestSHA256::DigestInfo() { - init_func - return baSHA1DigestInfo; -} - -ByteDynArray CDigestSHA256::DigestGetOperationState() { - init_func - throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); -} - -void CDigestSHA256::DigestSetOperationState(ByteArray &OperationState) { - init_func - throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); -} - -/* ******************** */ -/* MD5 */ -/* ******************** */ -CDigestMD5::CDigestMD5(std::shared_ptr Session) : CDigest(CKM_MD5, std::move(Session)) {} -CDigestMD5::~CDigestMD5() {} - -void CDigestMD5::DigestInit() { - init_func - data.clear(); -} - -void CDigestMD5::DigestUpdate(ByteArray &Part) { - init_func - data.append(Part); -} - -void CDigestMD5::DigestFinal(ByteArray &Digest) { - init_func - - // data.append(Digest); - ByteDynArray dataOut(MD5_DIGEST_LENGTH); - dataOut = md5.Digest(data);//, dataOut); - Digest.copy(dataOut); -} - - -CK_ULONG CDigestMD5::DigestLength() { - init_func - return MD5_DIGEST_LENGTH; -} - -ByteArray CDigestMD5::DigestInfo() { - init_func - return baMD5DigestInfo; -} - -ByteDynArray CDigestMD5::DigestGetOperationState() { - init_func - throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); -} - -void CDigestMD5::DigestSetOperationState(ByteArray &OperationState) { - init_func - throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); -} - -/* ******************** */ -/* Verify RSA */ -/* ******************** */ -CVerifyRSA::CVerifyRSA(CK_MECHANISM_TYPE type, std::shared_ptr Session) : CVerify(type, std::move(Session)) {} -CVerifyRSA::~CVerifyRSA() {} - -bool CVerifyRSA::VerifySupportMultipart() { - init_func - return false; -} - -CK_ULONG CVerifyRSA::VerifyLength() { - init_func - - std::shared_ptr pObject = pSession->pSlot->GetObjectFromID(hVerifyKey); - ER_ASSERT(pObject != nullptr, ERR_CANT_GET_OBJECT) - ER_ASSERT(pObject->ObjClass == CKO_PUBLIC_KEY, ERR_WRONG_OBJECT_TYPE) - auto pPublicKey = std::static_pointer_cast(pObject); - - ByteArray *baKeyModule = pPublicKey->getAttribute(CKA_MODULUS); - ER_ASSERT(!baKeyModule->isNull(), ERR_CANT_GET_PUBKEY_MODULUS) - return (CK_ULONG)baKeyModule->size(); -} - -ByteDynArray CVerifyRSA::VerifyDecryptSignature(ByteArray &Signature) { - init_func - ByteArray *baKeyExponent = nullptr, *baKeyModule = nullptr; - - std::shared_ptr pObject = pSession->pSlot->GetObjectFromID(hVerifyKey); - ER_ASSERT(pObject != nullptr, ERR_CANT_GET_OBJECT) - ER_ASSERT(pObject->ObjClass == CKO_PUBLIC_KEY, ERR_WRONG_OBJECT_TYPE) - auto pPublicKey = std::static_pointer_cast(pObject); - - baKeyExponent = pPublicKey->getAttribute(CKA_PUBLIC_EXPONENT); - ER_ASSERT(baKeyExponent != nullptr, ERR_CANT_GET_PUBKEY_EXPONENT) - - baKeyModule = pPublicKey->getAttribute(CKA_MODULUS); - ER_ASSERT(baKeyModule != nullptr, ERR_CANT_GET_PUBKEY_MODULUS) - - if (Signature.size() != baKeyModule->size()) - throw p11_error(CKR_SIGNATURE_LEN_RANGE); - - CRSA rsa(*baKeyModule, *baKeyExponent); - return rsa.RSA_PURE(Signature); -} - -ByteDynArray CVerifyRSA::VerifyGetOperationState() { - init_func - return ByteDynArray(); -} - -void CVerifyRSA::VerifySetOperationState(ByteArray &OperationState) { - init_func - if (OperationState.size() != 0) - throw p11_error(CKR_SAVED_STATE_INVALID); -} - -/* ******************** */ -/* VerifyRecover RSA */ -/* ******************** */ -CVerifyRecoverRSA::CVerifyRecoverRSA(CK_MECHANISM_TYPE type, std::shared_ptr Session) : CVerifyRecover(type, std::move(Session)) {} -CVerifyRecoverRSA::~CVerifyRecoverRSA() {} - -CK_ULONG CVerifyRecoverRSA::VerifyRecoverLength() { - init_func - - std::shared_ptr pObject = pSession->pSlot->GetObjectFromID(hVerifyRecoverKey); - ER_ASSERT(pObject != nullptr, ERR_CANT_GET_OBJECT) - ER_ASSERT(pObject->ObjClass == CKO_PUBLIC_KEY, ERR_WRONG_OBJECT_TYPE) - auto pPublicKey = std::static_pointer_cast(pObject); - - ByteArray *baKeyModule = pPublicKey->getAttribute(CKA_MODULUS); - ER_ASSERT(baKeyModule != nullptr, ERR_CANT_GET_PUBKEY_MODULUS) - return (CK_ULONG )baKeyModule->size(); -} - -ByteDynArray CVerifyRecoverRSA::VerifyRecoverDecryptSignature(ByteArray &Signature) { - init_func - ByteArray *baKeyExponent = nullptr, *baKeyModule = nullptr; - - std::shared_ptr pObject = pSession->pSlot->GetObjectFromID(hVerifyRecoverKey); - ER_ASSERT(pObject != nullptr, ERR_CANT_GET_OBJECT) - ER_ASSERT(pObject->ObjClass == CKO_PUBLIC_KEY, ERR_WRONG_OBJECT_TYPE) - auto pPublicKey = std::static_pointer_cast(pObject); - - pPublicKey->getAttribute(CKA_PUBLIC_EXPONENT); - ER_ASSERT(baKeyExponent != nullptr, ERR_CANT_GET_PUBKEY_EXPONENT); - - baKeyModule = pPublicKey->getAttribute(CKA_MODULUS); - ER_ASSERT(baKeyModule != nullptr, ERR_CANT_GET_PUBKEY_MODULUS) - - if (Signature.size() != baKeyModule->size()) - throw p11_error(CKR_SIGNATURE_LEN_RANGE); - - CRSA rsa(*baKeyModule, *baKeyExponent); - return rsa.RSA_PURE(Signature); -} - -ByteDynArray CVerifyRecoverRSA::VerifyRecoverGetOperationState() { - init_func - return ByteDynArray(); -} - -void CVerifyRecoverRSA::VerifyRecoverSetOperationState(ByteArray &OperationState) { - init_func - if (OperationState.size() != 0) - throw p11_error(CKR_SAVED_STATE_INVALID); -} - -/* ******************** */ -/* SignRSA */ -/* ******************** */ -CSignRSA::CSignRSA(CK_MECHANISM_TYPE type, std::shared_ptr Session) : CSign(type, std::move(Session)) {} -CSignRSA::~CSignRSA() {} - -bool CSignRSA::SignSupportMultipart() { - init_func - return false; -} - -CK_ULONG CSignRSA::SignLength() { - init_func - std::shared_ptr pObject = pSession->pSlot->GetObjectFromID(hSignKey); - ER_ASSERT(pObject != nullptr, ERR_CANT_GET_OBJECT) - ER_ASSERT(pObject->ObjClass == CKO_PRIVATE_KEY, ERR_WRONG_OBJECT_TYPE) - auto pPrivateKey = std::static_pointer_cast(pObject); - - ByteArray *baKeyModule = pPrivateKey->getAttribute(CKA_MODULUS); - ER_ASSERT(baKeyModule != nullptr, ERR_CANT_GET_PUBKEY_MODULUS) - return (CK_ULONG )baKeyModule->size(); -} - -ByteDynArray CSignRSA::SignGetOperationState() { - init_func - return ByteDynArray(); -} - -void CSignRSA::SignSetOperationState(ByteArray &OperationState) { - init_func - if (OperationState.size() != 0) - throw p11_error(CKR_SAVED_STATE_INVALID); -} - -/* ******************** */ -/* SignRecoverRSA */ -/* ******************** */ -CSignRecoverRSA::CSignRecoverRSA(CK_MECHANISM_TYPE type, std::shared_ptr Session) : CSignRecover(type, std::move(Session)) {} -CSignRecoverRSA::~CSignRecoverRSA() {} - -CK_ULONG CSignRecoverRSA::SignRecoverLength() { - init_func - std::shared_ptr pObject = pSession->pSlot->GetObjectFromID(hSignRecoverKey); - ER_ASSERT(pObject != nullptr, ERR_CANT_GET_OBJECT) - ER_ASSERT(pObject->ObjClass == CKO_PRIVATE_KEY, ERR_WRONG_OBJECT_TYPE) - auto pPrivateKey = std::static_pointer_cast(pObject); - - ByteArray *baKeyModule = pPrivateKey->getAttribute(CKA_MODULUS); - ER_ASSERT(baKeyModule != nullptr, ERR_CANT_GET_PUBKEY_MODULUS) - return (CK_ULONG )baKeyModule->size(); -} - -ByteDynArray CSignRecoverRSA::SignRecoverGetOperationState() { - init_func - return ByteDynArray(); -} - -void CSignRecoverRSA::SignRecoverSetOperationState(ByteArray &OperationState) { - init_func - if (OperationState.size() != 0) - throw p11_error(CKR_SAVED_STATE_INVALID); -} - -///* ******************** */ -///* RSA_X509 */ -///* ******************** */ -//CRSA_X509::CRSA_X509(std::shared_ptr Session) : CSignRSA(CKM_RSA_X_509, Session), -// CSignRecoverRSA(CKM_RSA_X_509, Session), -// CVerifyRSA(CKM_RSA_X_509, Session), -// CVerifyRecoverRSA(CKM_RSA_X_509, Session), -// CEncryptRSA(CKM_RSA_X_509, Session), -// CDecryptRSA(CKM_RSA_X_509, Session) {} -//CRSA_X509::~CRSA_X509() {} - -//void CRSA_X509::VerifyInit(CK_OBJECT_HANDLE PublicKey) { -// init_func -// hVerifyKey = PublicKey; -//} - -//void CRSA_X509::VerifyUpdate(ByteArray &Part) { -// init_func -// auto dwSize = baVerifyBuffer.size(); -// baVerifyBuffer.resize(dwSize + Part.size(), true); -// baVerifyBuffer.mid(dwSize, Part.size()).copy(Part); -//} - -//void CRSA_X509::VerifyFinal(ByteArray &Signature) -//{ -// init_func -// ByteDynArray baPlainSignature; -// CK_ULONG ulVerifyLength = VerifyLength(); - -// if (Signature.size() != ulVerifyLength) -// throw p11_error(CKR_SIGNATURE_LEN_RANGE); - -// // il buffer da verificare può anche essere -// // più corto della chiave, viene paddato automaticamente -// // specifiche P11 -// if (baVerifyBuffer.size() > ulVerifyLength) -// throw p11_error(CKR_DATA_LEN_RANGE); - -// baPlainSignature = VerifyDecryptSignature(Signature); - -// ByteDynArray baExpectedResult(ulVerifyLength); -// baExpectedResult.rightcopy(baVerifyBuffer); -// PutPaddingBT0(baExpectedResult, baVerifyBuffer.size()); - -// if (baPlainSignature == baExpectedResult) -// return; -// else -// throw p11_error(CKR_SIGNATURE_INVALID); -//} - -//void CRSA_X509::VerifyRecoverInit(CK_OBJECT_HANDLE PublicKey) { -// init_func -// hVerifyRecoverKey = PublicKey; -//} - -//ByteDynArray CRSA_X509::VerifyRecover(ByteArray &Signature) -//{ -// init_func -// CK_ULONG ulVerifyRecoverLength = VerifyRecoverLength(); - -// if (Signature.size() != ulVerifyRecoverLength) -// throw p11_error(CKR_SIGNATURE_LEN_RANGE); - -// return VerifyRecoverDecryptSignature(Signature); -//} - -//void CRSA_X509::SignInit(CK_OBJECT_HANDLE PrivateKey) -//{ -// init_func -// hSignKey = PrivateKey; -//} - -//void CRSA_X509::SignReset() -//{ -// init_func -// baSignBuffer.clear(); -//} - -//void CRSA_X509::SignUpdate(ByteArray &Part) { -// init_func -// auto dwSize = baSignBuffer.size(); -// baSignBuffer.resize(dwSize + Part.size(), true); -// baSignBuffer.mid(dwSize, Part.size()).copy(Part); -//} - -//ByteDynArray CRSA_X509::SignFinal() -//{ -// init_func -// CK_ULONG ulSignatureLength = SignLength(); - -// if (baSignBuffer.size() > ulSignatureLength) -// throw p11_error(CKR_DATA_LEN_RANGE); - -// return baSignBuffer; -//} - -//void CRSA_X509::SignRecoverInit(CK_OBJECT_HANDLE PrivateKey) { -// init_func -// hSignRecoverKey = PrivateKey; -//} - -//ByteDynArray CRSA_X509::SignRecover(ByteArray &Data) { -// init_func - -// CK_ULONG ulSignatureLength = SignRecoverLength(); - -// if (Data.size() > ulSignatureLength) -// throw p11_error(CKR_DATA_LEN_RANGE); - -// return Data; - -//} - -//void CRSA_X509::EncryptInit(CK_OBJECT_HANDLE PublicKey) { -// init_func -// hEncryptKey = PublicKey; -//} - -//ByteDynArray CRSA_X509::EncryptUpdate(ByteArray &Part) { -// init_func -// auto dwSize = baEncryptBuffer.size(); -// baEncryptBuffer.resize(dwSize + Part.size(), true); -// baEncryptBuffer.mid(dwSize, Part.size()).copy(Part); -// return ByteDynArray(); -//} - -//ByteDynArray CRSA_X509::EncryptFinal() -//{ -// init_func -// CK_ULONG ulEncryptLength = EncryptLength(); - -// if (baEncryptBuffer.size() > ulEncryptLength) -// throw p11_error(CKR_DATA_LEN_RANGE); - -// ByteDynArray baPlainData(ulEncryptLength); -// baPlainData.rightcopy(baEncryptBuffer); -// PutPaddingBT0(baPlainData, baEncryptBuffer.size()); - -// return EncryptCompute(baPlainData); -//} - -//void CRSA_X509::DecryptInit(CK_OBJECT_HANDLE PrivateKey) -//{ -// init_func -// hDecryptKey = PrivateKey; -//} - -//ByteDynArray CRSA_X509::DecryptUpdate(ByteArray &Part) { -// init_func -// auto dwSize = baDecryptBuffer.size(); -// baDecryptBuffer.resize(dwSize + Part.size(), true); -// baDecryptBuffer.mid(dwSize, Part.size()).copy(Part); -// return ByteDynArray(); -//} - -//ByteDynArray CRSA_X509::DecryptFinal() -//{ -// init_func -// CK_ULONG ulDecryptLength = DecryptLength(); - -// // nella decrypt il buffer deve essere lungo esasttamente k -// // (specifiche P11) -// if (baDecryptBuffer.size() != ulDecryptLength) -// throw p11_error(CKR_ENCRYPTED_DATA_LEN_RANGE); - -// return baDecryptBuffer; - -//} - -//ByteDynArray CRSA_X509::DecryptRemovePadding(ByteArray &paddedData) -//{ -// init_func -// // non faccio nullptra perchè l'RSA_X509 non leva il padding -// return paddedData; -//} - -/* ******************** */ -/* RSA_PKCS1 */ -/* ******************** */ -CRSA_PKCS1::CRSA_PKCS1(std::shared_ptr Session) : CSignRSA(CKM_RSA_PKCS, Session), - CSignRecoverRSA(CKM_RSA_PKCS, Session), - CVerifyRSA(CKM_RSA_PKCS, Session), - CVerifyRecoverRSA(CKM_RSA_PKCS, Session) /*, - CEncryptRSA(CKM_RSA_PKCS, Session), - CDecryptRSA(CKM_RSA_PKCS, Session) */ -{} -CRSA_PKCS1::~CRSA_PKCS1() {} - -void CRSA_PKCS1::VerifyInit(CK_OBJECT_HANDLE PublicKey) { - init_func - hVerifyKey = PublicKey; -} - -void CRSA_PKCS1::VerifyUpdate(ByteArray &Part) { - init_func - auto dwSize = baVerifyBuffer.size(); - baVerifyBuffer.resize(dwSize + Part.size(), true); - baVerifyBuffer.mid(dwSize, Part.size()).copy(Part); -} - -void CRSA_PKCS1::VerifyFinal(ByteArray &Signature) { - init_func - ByteDynArray baPlainSignature; - CK_ULONG ulVerifyLength = VerifyLength(); - - if (Signature.size() != ulVerifyLength) - throw p11_error(CKR_SIGNATURE_LEN_RANGE); - - // max k-11 (specifiche p11) - if (baVerifyBuffer.size() > ulVerifyLength - 11) - throw p11_error(CKR_DATA_LEN_RANGE); - - baPlainSignature = VerifyDecryptSignature(Signature); - - ByteDynArray baExpectedResult(ulVerifyLength); - baExpectedResult.rightcopy(baVerifyBuffer); - PutPaddingBT1(baExpectedResult, baVerifyBuffer.size()); - - if (baPlainSignature == baExpectedResult) - return; - else - throw p11_error(CKR_SIGNATURE_INVALID); -} - -void CRSA_PKCS1::VerifyRecoverInit(CK_OBJECT_HANDLE PublicKey) { - init_func - hVerifyRecoverKey = PublicKey; -} - -ByteDynArray CRSA_PKCS1::VerifyRecover(ByteArray &Signature) { - init_func - CK_ULONG ulVerifyRecoverLength = VerifyRecoverLength(); - - if (Signature.size() != ulVerifyRecoverLength) - throw p11_error(CKR_SIGNATURE_LEN_RANGE); - - ByteDynArray baPlainSignature = VerifyRecoverDecryptSignature(Signature); - - // se non posso levare il padding, la firma ha - // qualcosa di sbagliato - size_t dwPadLen; - try { - dwPadLen = RemovePaddingBT1(baPlainSignature); - } catch (...) { - throw p11_error(CKR_SIGNATURE_INVALID); - } - - // i dati restutuiti non possono essere più - // lunghi di k-11!! (specifiche p11) - auto Data = baPlainSignature.mid(dwPadLen); - if (Data.size() > ulVerifyRecoverLength - 11) - throw p11_error(CKR_DATA_LEN_RANGE); - return Data; -} - -void CRSA_PKCS1::SignInit(CK_OBJECT_HANDLE PrivateKey) { - init_func - hSignKey = PrivateKey; -} - -void CRSA_PKCS1::SignReset() { - init_func - baSignBuffer.clear(); -} - -void CRSA_PKCS1::SignUpdate(ByteArray &Part) { - init_func - auto dwSize = baSignBuffer.size(); - baSignBuffer.resize(dwSize + Part.size(), true); - baSignBuffer.mid(dwSize, Part.size()).copy(Part); -} - -ByteDynArray CRSA_PKCS1::SignFinal() { - init_func - CK_ULONG ulSignatureLength = SignLength(); - - // al massimo k-11 bytes (specifiche p11) - if (baSignBuffer.size() > ulSignatureLength - 11) - throw p11_error(CKR_DATA_LEN_RANGE); - - return baSignBuffer; -} - -void CRSA_PKCS1::SignRecoverInit(CK_OBJECT_HANDLE PrivateKey) { - init_func - hSignRecoverKey = PrivateKey; -} - -ByteDynArray CRSA_PKCS1::SignRecover(ByteArray &Data) { - init_func - - CK_ULONG ulSignatureLength = SignRecoverLength(); - - // al massimo k-11 bytes (specifiche p11) - if (Data.size() > ulSignatureLength - 11) - throw p11_error(CKR_DATA_LEN_RANGE); - - return Data; - -} -//void CRSA_PKCS1::EncryptInit(CK_OBJECT_HANDLE PublicKey) { -// init_func -// hEncryptKey = PublicKey; -//} - -//ByteDynArray CRSA_PKCS1::EncryptUpdate(ByteArray &Part) { -// init_func -// auto dwSize = baEncryptBuffer.size(); -// baEncryptBuffer.resize(dwSize + Part.size(), true); -// baEncryptBuffer.mid(dwSize, Part.size()).copy(Part); -// return ByteDynArray(); -//} - -//ByteDynArray CRSA_PKCS1::EncryptFinal() -//{ -// init_func -// CK_ULONG ulEncryptLength = EncryptLength(); - -// // al massimo k-11 bytes (specifiche p11) -// if (baEncryptBuffer.size() > (ulEncryptLength - 11)) -// throw p11_error(CKR_DATA_LEN_RANGE); - -// ByteDynArray baPlainData(ulEncryptLength); -// baPlainData.rightcopy(baEncryptBuffer); -// PutPaddingBT2(baPlainData, baEncryptBuffer.size()); - -// return EncryptCompute(baPlainData); - -//} - -//void CRSA_PKCS1::DecryptInit(CK_OBJECT_HANDLE PrivateKey) -//{ -// init_func -// hDecryptKey = PrivateKey; -//} - -//ByteDynArray CRSA_PKCS1::DecryptUpdate(ByteArray &Part) { -// init_func -// auto dwSize = baDecryptBuffer.size(); -// baDecryptBuffer.resize(dwSize + Part.size(), true); -// baDecryptBuffer.mid(dwSize, Part.size()).copy(Part); -// return ByteDynArray(); -//} - -//ByteDynArray CRSA_PKCS1::DecryptFinal() -//{ -// init_func -// CK_ULONG ulDecryptLength = DecryptLength(); - -// // esattamente k bytes (specifiche p11, ma mi sembra ovvio!) -// if (baDecryptBuffer.size() != ulDecryptLength) -// throw p11_error(CKR_ENCRYPTED_DATA_LEN_RANGE); - -// return baDecryptBuffer; -//} - -//ByteDynArray CRSA_PKCS1::DecryptRemovePadding(ByteArray &paddedData) -//{ -// init_func - -// // devo levare il padding BT2 da paddedData e copiare tutto in unpaddedData; -// // se non posso levare il padding i dati criptati non sono validi! -// size_t dwPaddingLen; -// try { -// dwPaddingLen = RemovePaddingBT2(paddedData); -// } -// catch (...) { -// throw p11_error(CKR_ENCRYPTED_DATA_INVALID); -// } - -// auto unpaddedData = paddedData.mid(dwPaddingLen); - -// // i dati possono essere lunghi al massiko k-11 -// // (specifiche p11) -// if (unpaddedData.size() > paddedData.size() - 11) -// throw p11_error(CKR_ENCRYPTED_DATA_INVALID); - -// return unpaddedData; -//} - -/* ************************ */ -/* SignRSA_withDigest */ -/* ************************ */ - -CSignRSAwithDigest::CSignRSAwithDigest(CK_MECHANISM_TYPE type, std::shared_ptr Session, CDigest *Digest) : pDigest(Digest), CSignRSA(type, std::move(Session)) {} -CSignRSAwithDigest::~CSignRSAwithDigest() {} - -bool CSignRSAwithDigest::SignSupportMultipart() { - init_func - return true; -} - -void CSignRSAwithDigest::SignInit(CK_OBJECT_HANDLE hPrivateKey) { - init_func - hSignKey = hPrivateKey; - pDigest->DigestInit(); -} - -void CSignRSAwithDigest::SignReset() { - init_func - pDigest->DigestInit(); -} - - -void CSignRSAwithDigest::SignUpdate(ByteArray &Part) { - init_func - pDigest->DigestUpdate(Part); -} - -ByteDynArray CSignRSAwithDigest::SignFinal() { - init_func - CK_ULONG ulDigestLength = pDigest->DigestLength(); - - ByteDynArray SignBuffer(ulDigestLength); - pDigest->DigestFinal(SignBuffer); - - ByteDynArray baDigestInfo = pDigest->DigestInfo(); - - return baDigestInfo.append(SignBuffer); -} - -ByteDynArray CSignRSAwithDigest::SignGetOperationState() { - init_func - return pDigest->DigestGetOperationState(); -} - -void CSignRSAwithDigest::SignSetOperationState(ByteArray &OperationState) { - init_func - pDigest->DigestSetOperationState(OperationState); -} - -/* ************************ */ -/* VerifyRSA_withDigest */ -/* ************************ */ - -CVerifyRSAwithDigest::CVerifyRSAwithDigest(CK_MECHANISM_TYPE type, std::shared_ptr Session, CDigest *Digest) : pDigest(Digest), CVerifyRSA(type, std::move(Session)) {} -CVerifyRSAwithDigest::~CVerifyRSAwithDigest() {} - -bool CVerifyRSAwithDigest::VerifySupportMultipart() { - init_func - return true; -} - -void CVerifyRSAwithDigest::VerifyInit(CK_OBJECT_HANDLE PublicKey) { - init_func - hVerifyKey = PublicKey; - pDigest->DigestInit(); -} - -void CVerifyRSAwithDigest::VerifyUpdate(ByteArray &Part) { - init_func - pDigest->DigestUpdate(Part); -} - -void CVerifyRSAwithDigest::VerifyFinal(ByteArray &Signature) { - init_func - ByteDynArray baPlainSignature; - CK_ULONG ulVerifyLength = VerifyLength(); - - if (Signature.size() != ulVerifyLength) - throw p11_error(CKR_SIGNATURE_LEN_RANGE); - - baPlainSignature = VerifyDecryptSignature(Signature); - - ByteDynArray baExpectedResult(ulVerifyLength); - CK_ULONG ulDigestLen = pDigest->DigestLength(); - ByteArray baDigestInfo = pDigest->DigestInfo(); - - ByteArray ba1 = baExpectedResult.right(ulDigestLen); - pDigest->DigestFinal(ba1); - baExpectedResult.rightcopy(baDigestInfo, ulDigestLen); - PutPaddingBT1(baExpectedResult, ulDigestLen + baDigestInfo.size()); - - if (baPlainSignature == baExpectedResult) - return; - else - throw p11_error(CKR_SIGNATURE_INVALID); -} - -ByteDynArray CVerifyRSAwithDigest::VerifyGetOperationState() { - init_func - return pDigest->DigestGetOperationState(); -} - -void CVerifyRSAwithDigest::VerifySetOperationState(ByteArray &OperationState) { - init_func - pDigest->DigestSetOperationState(OperationState); -} -/* ******************** */ -/* RSA_withMD5 */ -/* ******************** */ -CRSAwithMD5::CRSAwithMD5(std::shared_ptr Session) : CSignRSAwithDigest(CKM_MD5_RSA_PKCS, Session, &md5), CVerifyRSAwithDigest(CKM_MD5_RSA_PKCS, Session, &md5), md5(Session) {} -CRSAwithMD5::~CRSAwithMD5() {} - -/* ******************** */ -/* RSA_withSHA1 */ -/* ******************** */ -CRSAwithSHA1::CRSAwithSHA1(std::shared_ptr Session) : CSignRSAwithDigest(CKM_SHA1_RSA_PKCS, Session, &sha1), CVerifyRSAwithDigest(CKM_SHA1_RSA_PKCS, Session, &sha1), sha1(Session) {} -CRSAwithSHA1::~CRSAwithSHA1() {} - -/* ******************** */ -/* RSA_withSHA1 */ -/* ******************** */ -CRSAwithSHA256::CRSAwithSHA256(std::shared_ptr Session) : CSignRSAwithDigest(CKM_SHA256_RSA_PKCS, Session, &sha256), CVerifyRSAwithDigest(CKM_SHA256_RSA_PKCS, Session, &sha256), sha256(Session) {} -CRSAwithSHA256::~CRSAwithSHA256() {} - -///* ******************** */ -///* EncryptRSA */ -///* ******************** */ -//CEncryptRSA::CEncryptRSA(CK_MECHANISM_TYPE type, std::shared_ptr Session) : CEncrypt(type, std::move(Session)) {} -//CEncryptRSA::~CEncryptRSA() {} - -//bool CEncryptRSA::EncryptSupportMultipart() { -// init_func -// return false; -//} - -//CK_ULONG CEncryptRSA::EncryptLength() { -// init_func -// std::shared_ptr pObject = pSession->pSlot->GetObjectFromID(hEncryptKey); -// ER_ASSERT(pObject != nullptr, ERR_CANT_GET_OBJECT) -// ER_ASSERT(pObject->ObjClass == CKO_PUBLIC_KEY, ERR_WRONG_OBJECT_TYPE) -// auto pPrivateKey = std::static_pointer_cast(pObject); - -// ByteArray *baKeyModule = pPrivateKey->getAttribute(CKA_MODULUS); -// ER_ASSERT(baKeyModule != nullptr, ERR_CANT_GET_PUBKEY_MODULUS) -// return (CK_ULONG)baKeyModule->size(); -//} - -//ByteDynArray CEncryptRSA::EncryptCompute(ByteArray &baPlainData) -//{ -// init_func -// ByteArray *baKeyExponent = nullptr, *baKeyModule = nullptr; - -// std::shared_ptr pObject = pSession->pSlot->GetObjectFromID(hEncryptKey); -// ER_ASSERT(pObject != nullptr, ERR_CANT_GET_OBJECT) -// ER_ASSERT(pObject->ObjClass == CKO_PUBLIC_KEY, ERR_WRONG_OBJECT_TYPE) -// auto pPublicKey = std::static_pointer_cast(pObject); - -// baKeyExponent = pPublicKey->getAttribute(CKA_PUBLIC_EXPONENT); -// ER_ASSERT(baKeyExponent != nullptr, ERR_CANT_GET_PUBKEY_EXPONENT) - -// baKeyModule = pPublicKey->getAttribute(CKA_MODULUS); -// ER_ASSERT(baKeyModule != nullptr, ERR_CANT_GET_PUBKEY_MODULUS) - -// auto dwKeyLenBytes = baKeyModule->size(); - -// // è molto strano che baPlainData non sia lungo quanto la chiave... -// // il controllo su CKR_DATA_LEN_RANGE è stato fatto prima, ma -// // lo uso anche in questo caso -// if (baPlainData.size() != dwKeyLenBytes) -// throw p11_error(CKR_DATA_LEN_RANGE); - -// CRSA rsa(*baKeyModule, *baKeyExponent); -// return rsa.RSA_PURE(baPlainData); -//} - -//ByteDynArray CEncryptRSA::EncryptGetOperationState() -//{ -// init_func -// return ByteDynArray(); -//} - -//void CEncryptRSA::EncryptSetOperationState(ByteArray &OperationState) -//{ -// init_func -// if (OperationState.size() != 0) -// throw p11_error(CKR_SAVED_STATE_INVALID); -//} - -/* ******************** */ -/* DecryptRSA */ -/* ******************** */ -//CDecryptRSA::CDecryptRSA() {} -/*CDecryptRSA::CDecryptRSA(CK_MECHANISM_TYPE type, std::shared_ptr Session) : CDecrypt(type, std::move(Session)) {} -CDecryptRSA::~CDecryptRSA() {} - -bool CDecryptRSA::DecryptSupportMultipart() { - init_func - return false; -} - -CK_ULONG CDecryptRSA::DecryptLength() { - init_func - std::shared_ptr pObject = pSession->pSlot->GetObjectFromID(hDecryptKey); - ER_ASSERT(pObject != nullptr, ERR_CANT_GET_OBJECT) - ER_ASSERT(pObject->ObjClass == CKO_PRIVATE_KEY, ERR_WRONG_OBJECT_TYPE) - auto pPrivateKey = std::static_pointer_cast(pObject); - - ByteArray *baKeyModule = pPrivateKey->getAttribute(CKA_MODULUS); - ER_ASSERT(baKeyModule != nullptr, ERR_CANT_GET_PUBKEY_MODULUS) - return (CK_ULONG)baKeyModule->size(); -} - -ByteDynArray CDecryptRSA::DecryptGetOperationState() -{ - init_func - return ByteDynArray(); -} - -void CDecryptRSA::DecryptSetOperationState(ByteArray &OperationState) -{ - init_func - if (OperationState.size() != 0) - throw p11_error(CKR_SAVED_STATE_INVALID); -}*/ - -} + +#include "Mechanism.h" +#include "../Crypto/RSA.h" +#include "P11Object.h" +#include "../Util/util.h" + +extern CLog Log; + +//static char *szCompiledFile=__FILE__; + +static BYTE SHA1_RSAcode[]= {0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x05,0x00,0x04,0x14}; +static BYTE MD5_RSAcode[]= {0x30,0x20,0x30,0x0C,0x06,0x08,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x05,0x05,0x00,0x04,0x10}; +static ByteArray baSHA1DigestInfo(SHA1_RSAcode,sizeof(SHA1_RSAcode)); +static ByteArray baMD5DigestInfo(MD5_RSAcode,sizeof(MD5_RSAcode)); + +namespace p11 { + +CMechanism::CMechanism(CK_MECHANISM_TYPE type, std::shared_ptr Session) : mtType(type), pSession(std::move(Session)) {} +CMechanism::~CMechanism() {} +/*bool CDecrypt::checkCache(ByteArray &Data, ByteArray &Result) +{ + init_func + if (Data.data() == cacheData.data() && Data.size() == cacheData.size()) { + if (!Result.isNull()) { + if (Result.size() < resultCache.size()) + throw new p11_error(CKR_BUFFER_TOO_SMALL); + + Result.copy(resultCache); + Result = Result.left(resultCache.size()); + return true; + } + } + return false; +} + +void CDecrypt::setCache(ByteArray &Data, ByteArray &Result) +{ + init_func + cacheData = Data; + resultCache = Result; +}*/ + +CVerify::CVerify(CK_MECHANISM_TYPE type, std::shared_ptr Session) : CMechanism(type, std::move(Session)) {} +CVerify::~CVerify() {} + +CVerifyRecover::CVerifyRecover(CK_MECHANISM_TYPE type, std::shared_ptr Session) : CMechanism(type, std::move(Session)) {} +CVerifyRecover::~CVerifyRecover() {} + +CDigest::CDigest(CK_MECHANISM_TYPE type, std::shared_ptr Session) : CMechanism(type, std::move(Session)) {} +CDigest::~CDigest() {} + +CSign::CSign(CK_MECHANISM_TYPE type, std::shared_ptr Session) : CMechanism(type, std::move(Session)) {} +CSign::~CSign() {} + +CSignRecover::CSignRecover(CK_MECHANISM_TYPE type, std::shared_ptr Session) : CMechanism(type, std::move(Session)) {} +CSignRecover::~CSignRecover() {} + +/*CEncrypt::CEncrypt(CK_MECHANISM_TYPE type, std::shared_ptr Session) : CMechanism(type, std::move(Session)) {} +CEncrypt::~CEncrypt() {} + +BYTE CDecrypt::uninitializedCacheData = 0; +CDecrypt::CDecrypt(CK_MECHANISM_TYPE type, std::shared_ptr Session) + : CMechanism(type, Session), cacheData(&uninitializedCacheData, 1) {} +CDecrypt::~CDecrypt() {}*/ + +/* ******************** */ +/* SHA1 */ +/* ******************** */ +CDigestSHA::CDigestSHA(std::shared_ptr Session) : CDigest(CKM_SHA_1, std::move(Session)) {} +CDigestSHA::~CDigestSHA() {} + +void CDigestSHA::DigestInit() { + init_func + data.clear(); +} + +void CDigestSHA::DigestUpdate(ByteArray &Part) { + init_func + data.append(Part); +} + +void CDigestSHA::DigestFinal(ByteArray &Digest) { + init_func + + // data.append(Digest); + ByteDynArray dataOut(SHA_DIGEST_LENGTH); + dataOut = sha1.Digest(data);//, dataOut); + Digest.copy(dataOut); +} + +CK_ULONG CDigestSHA::DigestLength() { + init_func + return SHA_DIGEST_LENGTH; +} + +ByteArray CDigestSHA::DigestInfo() { + init_func + return baSHA1DigestInfo; +} + +ByteDynArray CDigestSHA::DigestGetOperationState() { + init_func + throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); +} + +void CDigestSHA::DigestSetOperationState(ByteArray &OperationState) { + init_func + throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); +} + +/* ******************** */ +/* SHA256 */ +/* ******************** */ +CDigestSHA256::CDigestSHA256(std::shared_ptr Session) : CDigest(CKM_SHA_1, std::move(Session)) {} +CDigestSHA256::~CDigestSHA256() {} + +void CDigestSHA256::DigestInit() { + init_func + data.clear(); +} + +void CDigestSHA256::DigestUpdate(ByteArray &Part) { + init_func + data.append(Part); +} + +void CDigestSHA256::DigestFinal(ByteArray &Digest) { + init_func + + // data.append(Digest); + ByteDynArray dataOut(SHA256_DIGEST_LENGTH); + dataOut = sha256.Digest(data);//, dataOut); + Digest.copy(dataOut); +} + +CK_ULONG CDigestSHA256::DigestLength() { + init_func + return SHA256_DIGEST_LENGTH; +} + +ByteArray CDigestSHA256::DigestInfo() { + init_func + return baSHA1DigestInfo; +} + +ByteDynArray CDigestSHA256::DigestGetOperationState() { + init_func + throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); +} + +void CDigestSHA256::DigestSetOperationState(ByteArray &OperationState) { + init_func + throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); +} + +/* ******************** */ +/* MD5 */ +/* ******************** */ +CDigestMD5::CDigestMD5(std::shared_ptr Session) : CDigest(CKM_MD5, std::move(Session)) {} +CDigestMD5::~CDigestMD5() {} + +void CDigestMD5::DigestInit() { + init_func + data.clear(); +} + +void CDigestMD5::DigestUpdate(ByteArray &Part) { + init_func + data.append(Part); +} + +void CDigestMD5::DigestFinal(ByteArray &Digest) { + init_func + + // data.append(Digest); + ByteDynArray dataOut(MD5_DIGEST_LENGTH); + dataOut = md5.Digest(data);//, dataOut); + Digest.copy(dataOut); +} + + +CK_ULONG CDigestMD5::DigestLength() { + init_func + return MD5_DIGEST_LENGTH; +} + +ByteArray CDigestMD5::DigestInfo() { + init_func + return baMD5DigestInfo; +} + +ByteDynArray CDigestMD5::DigestGetOperationState() { + init_func + throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); +} + +void CDigestMD5::DigestSetOperationState(ByteArray &OperationState) { + init_func + throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); +} + +/* ******************** */ +/* Verify RSA */ +/* ******************** */ +CVerifyRSA::CVerifyRSA(CK_MECHANISM_TYPE type, std::shared_ptr Session) : CVerify(type, std::move(Session)) {} +CVerifyRSA::~CVerifyRSA() {} + +bool CVerifyRSA::VerifySupportMultipart() { + init_func + return false; +} + +CK_ULONG CVerifyRSA::VerifyLength() { + init_func + + std::shared_ptr pObject = pSession->pSlot->GetObjectFromID(hVerifyKey); + ER_ASSERT(pObject != nullptr, ERR_CANT_GET_OBJECT) + ER_ASSERT(pObject->ObjClass == CKO_PUBLIC_KEY, ERR_WRONG_OBJECT_TYPE) + auto pPublicKey = std::static_pointer_cast(pObject); + + ByteArray *baKeyModule = pPublicKey->getAttribute(CKA_MODULUS); + ER_ASSERT(!baKeyModule->isNull(), ERR_CANT_GET_PUBKEY_MODULUS) + return (CK_ULONG)baKeyModule->size(); +} + +ByteDynArray CVerifyRSA::VerifyDecryptSignature(ByteArray &Signature) { + init_func + ByteArray *baKeyExponent = nullptr, *baKeyModule = nullptr; + + std::shared_ptr pObject = pSession->pSlot->GetObjectFromID(hVerifyKey); + ER_ASSERT(pObject != nullptr, ERR_CANT_GET_OBJECT) + ER_ASSERT(pObject->ObjClass == CKO_PUBLIC_KEY, ERR_WRONG_OBJECT_TYPE) + auto pPublicKey = std::static_pointer_cast(pObject); + + baKeyExponent = pPublicKey->getAttribute(CKA_PUBLIC_EXPONENT); + ER_ASSERT(baKeyExponent != nullptr, ERR_CANT_GET_PUBKEY_EXPONENT) + + baKeyModule = pPublicKey->getAttribute(CKA_MODULUS); + ER_ASSERT(baKeyModule != nullptr, ERR_CANT_GET_PUBKEY_MODULUS) + + if (Signature.size() != baKeyModule->size()) + throw p11_error(CKR_SIGNATURE_LEN_RANGE); + + CRSA rsa(*baKeyModule, *baKeyExponent); + return rsa.RSA_PURE(Signature); +} + +ByteDynArray CVerifyRSA::VerifyGetOperationState() { + init_func + return ByteDynArray(); +} + +void CVerifyRSA::VerifySetOperationState(ByteArray &OperationState) { + init_func + if (OperationState.size() != 0) + throw p11_error(CKR_SAVED_STATE_INVALID); +} + +/* ******************** */ +/* VerifyRecover RSA */ +/* ******************** */ +CVerifyRecoverRSA::CVerifyRecoverRSA(CK_MECHANISM_TYPE type, std::shared_ptr Session) : CVerifyRecover(type, std::move(Session)) {} +CVerifyRecoverRSA::~CVerifyRecoverRSA() {} + +CK_ULONG CVerifyRecoverRSA::VerifyRecoverLength() { + init_func + + std::shared_ptr pObject = pSession->pSlot->GetObjectFromID(hVerifyRecoverKey); + ER_ASSERT(pObject != nullptr, ERR_CANT_GET_OBJECT) + ER_ASSERT(pObject->ObjClass == CKO_PUBLIC_KEY, ERR_WRONG_OBJECT_TYPE) + auto pPublicKey = std::static_pointer_cast(pObject); + + ByteArray *baKeyModule = pPublicKey->getAttribute(CKA_MODULUS); + ER_ASSERT(baKeyModule != nullptr, ERR_CANT_GET_PUBKEY_MODULUS) + return (CK_ULONG )baKeyModule->size(); +} + +ByteDynArray CVerifyRecoverRSA::VerifyRecoverDecryptSignature(ByteArray &Signature) { + init_func + ByteArray *baKeyExponent = nullptr, *baKeyModule = nullptr; + + std::shared_ptr pObject = pSession->pSlot->GetObjectFromID(hVerifyRecoverKey); + ER_ASSERT(pObject != nullptr, ERR_CANT_GET_OBJECT) + ER_ASSERT(pObject->ObjClass == CKO_PUBLIC_KEY, ERR_WRONG_OBJECT_TYPE) + auto pPublicKey = std::static_pointer_cast(pObject); + + pPublicKey->getAttribute(CKA_PUBLIC_EXPONENT); + ER_ASSERT(baKeyExponent != nullptr, ERR_CANT_GET_PUBKEY_EXPONENT); + + baKeyModule = pPublicKey->getAttribute(CKA_MODULUS); + ER_ASSERT(baKeyModule != nullptr, ERR_CANT_GET_PUBKEY_MODULUS) + + if (Signature.size() != baKeyModule->size()) + throw p11_error(CKR_SIGNATURE_LEN_RANGE); + + CRSA rsa(*baKeyModule, *baKeyExponent); + return rsa.RSA_PURE(Signature); +} + +ByteDynArray CVerifyRecoverRSA::VerifyRecoverGetOperationState() { + init_func + return ByteDynArray(); +} + +void CVerifyRecoverRSA::VerifyRecoverSetOperationState(ByteArray &OperationState) { + init_func + if (OperationState.size() != 0) + throw p11_error(CKR_SAVED_STATE_INVALID); +} + +/* ******************** */ +/* SignRSA */ +/* ******************** */ +CSignRSA::CSignRSA(CK_MECHANISM_TYPE type, std::shared_ptr Session) : CSign(type, std::move(Session)) {} +CSignRSA::~CSignRSA() {} + +bool CSignRSA::SignSupportMultipart() { + init_func + return false; +} + +CK_ULONG CSignRSA::SignLength() { + init_func + std::shared_ptr pObject = pSession->pSlot->GetObjectFromID(hSignKey); + ER_ASSERT(pObject != nullptr, ERR_CANT_GET_OBJECT) + ER_ASSERT(pObject->ObjClass == CKO_PRIVATE_KEY, ERR_WRONG_OBJECT_TYPE) + auto pPrivateKey = std::static_pointer_cast(pObject); + + ByteArray *baKeyModule = pPrivateKey->getAttribute(CKA_MODULUS); + ER_ASSERT(baKeyModule != nullptr, ERR_CANT_GET_PUBKEY_MODULUS) + return (CK_ULONG )baKeyModule->size(); +} + +ByteDynArray CSignRSA::SignGetOperationState() { + init_func + return ByteDynArray(); +} + +void CSignRSA::SignSetOperationState(ByteArray &OperationState) { + init_func + if (OperationState.size() != 0) + throw p11_error(CKR_SAVED_STATE_INVALID); +} + +/* ******************** */ +/* SignRecoverRSA */ +/* ******************** */ +CSignRecoverRSA::CSignRecoverRSA(CK_MECHANISM_TYPE type, std::shared_ptr Session) : CSignRecover(type, std::move(Session)) {} +CSignRecoverRSA::~CSignRecoverRSA() {} + +CK_ULONG CSignRecoverRSA::SignRecoverLength() { + init_func + std::shared_ptr pObject = pSession->pSlot->GetObjectFromID(hSignRecoverKey); + ER_ASSERT(pObject != nullptr, ERR_CANT_GET_OBJECT) + ER_ASSERT(pObject->ObjClass == CKO_PRIVATE_KEY, ERR_WRONG_OBJECT_TYPE) + auto pPrivateKey = std::static_pointer_cast(pObject); + + ByteArray *baKeyModule = pPrivateKey->getAttribute(CKA_MODULUS); + ER_ASSERT(baKeyModule != nullptr, ERR_CANT_GET_PUBKEY_MODULUS) + return (CK_ULONG )baKeyModule->size(); +} + +ByteDynArray CSignRecoverRSA::SignRecoverGetOperationState() { + init_func + return ByteDynArray(); +} + +void CSignRecoverRSA::SignRecoverSetOperationState(ByteArray &OperationState) { + init_func + if (OperationState.size() != 0) + throw p11_error(CKR_SAVED_STATE_INVALID); +} + +///* ******************** */ +///* RSA_X509 */ +///* ******************** */ +//CRSA_X509::CRSA_X509(std::shared_ptr Session) : CSignRSA(CKM_RSA_X_509, Session), +// CSignRecoverRSA(CKM_RSA_X_509, Session), +// CVerifyRSA(CKM_RSA_X_509, Session), +// CVerifyRecoverRSA(CKM_RSA_X_509, Session), +// CEncryptRSA(CKM_RSA_X_509, Session), +// CDecryptRSA(CKM_RSA_X_509, Session) {} +//CRSA_X509::~CRSA_X509() {} + +//void CRSA_X509::VerifyInit(CK_OBJECT_HANDLE PublicKey) { +// init_func +// hVerifyKey = PublicKey; +//} + +//void CRSA_X509::VerifyUpdate(ByteArray &Part) { +// init_func +// auto dwSize = baVerifyBuffer.size(); +// baVerifyBuffer.resize(dwSize + Part.size(), true); +// baVerifyBuffer.mid(dwSize, Part.size()).copy(Part); +//} + +//void CRSA_X509::VerifyFinal(ByteArray &Signature) +//{ +// init_func +// ByteDynArray baPlainSignature; +// CK_ULONG ulVerifyLength = VerifyLength(); + +// if (Signature.size() != ulVerifyLength) +// throw p11_error(CKR_SIGNATURE_LEN_RANGE); + +// // il buffer da verificare può anche essere +// // più corto della chiave, viene paddato automaticamente +// // specifiche P11 +// if (baVerifyBuffer.size() > ulVerifyLength) +// throw p11_error(CKR_DATA_LEN_RANGE); + +// baPlainSignature = VerifyDecryptSignature(Signature); + +// ByteDynArray baExpectedResult(ulVerifyLength); +// baExpectedResult.rightcopy(baVerifyBuffer); +// PutPaddingBT0(baExpectedResult, baVerifyBuffer.size()); + +// if (baPlainSignature == baExpectedResult) +// return; +// else +// throw p11_error(CKR_SIGNATURE_INVALID); +//} + +//void CRSA_X509::VerifyRecoverInit(CK_OBJECT_HANDLE PublicKey) { +// init_func +// hVerifyRecoverKey = PublicKey; +//} + +//ByteDynArray CRSA_X509::VerifyRecover(ByteArray &Signature) +//{ +// init_func +// CK_ULONG ulVerifyRecoverLength = VerifyRecoverLength(); + +// if (Signature.size() != ulVerifyRecoverLength) +// throw p11_error(CKR_SIGNATURE_LEN_RANGE); + +// return VerifyRecoverDecryptSignature(Signature); +//} + +//void CRSA_X509::SignInit(CK_OBJECT_HANDLE PrivateKey) +//{ +// init_func +// hSignKey = PrivateKey; +//} + +//void CRSA_X509::SignReset() +//{ +// init_func +// baSignBuffer.clear(); +//} + +//void CRSA_X509::SignUpdate(ByteArray &Part) { +// init_func +// auto dwSize = baSignBuffer.size(); +// baSignBuffer.resize(dwSize + Part.size(), true); +// baSignBuffer.mid(dwSize, Part.size()).copy(Part); +//} + +//ByteDynArray CRSA_X509::SignFinal() +//{ +// init_func +// CK_ULONG ulSignatureLength = SignLength(); + +// if (baSignBuffer.size() > ulSignatureLength) +// throw p11_error(CKR_DATA_LEN_RANGE); + +// return baSignBuffer; +//} + +//void CRSA_X509::SignRecoverInit(CK_OBJECT_HANDLE PrivateKey) { +// init_func +// hSignRecoverKey = PrivateKey; +//} + +//ByteDynArray CRSA_X509::SignRecover(ByteArray &Data) { +// init_func + +// CK_ULONG ulSignatureLength = SignRecoverLength(); + +// if (Data.size() > ulSignatureLength) +// throw p11_error(CKR_DATA_LEN_RANGE); + +// return Data; + +//} + +//void CRSA_X509::EncryptInit(CK_OBJECT_HANDLE PublicKey) { +// init_func +// hEncryptKey = PublicKey; +//} + +//ByteDynArray CRSA_X509::EncryptUpdate(ByteArray &Part) { +// init_func +// auto dwSize = baEncryptBuffer.size(); +// baEncryptBuffer.resize(dwSize + Part.size(), true); +// baEncryptBuffer.mid(dwSize, Part.size()).copy(Part); +// return ByteDynArray(); +//} + +//ByteDynArray CRSA_X509::EncryptFinal() +//{ +// init_func +// CK_ULONG ulEncryptLength = EncryptLength(); + +// if (baEncryptBuffer.size() > ulEncryptLength) +// throw p11_error(CKR_DATA_LEN_RANGE); + +// ByteDynArray baPlainData(ulEncryptLength); +// baPlainData.rightcopy(baEncryptBuffer); +// PutPaddingBT0(baPlainData, baEncryptBuffer.size()); + +// return EncryptCompute(baPlainData); +//} + +//void CRSA_X509::DecryptInit(CK_OBJECT_HANDLE PrivateKey) +//{ +// init_func +// hDecryptKey = PrivateKey; +//} + +//ByteDynArray CRSA_X509::DecryptUpdate(ByteArray &Part) { +// init_func +// auto dwSize = baDecryptBuffer.size(); +// baDecryptBuffer.resize(dwSize + Part.size(), true); +// baDecryptBuffer.mid(dwSize, Part.size()).copy(Part); +// return ByteDynArray(); +//} + +//ByteDynArray CRSA_X509::DecryptFinal() +//{ +// init_func +// CK_ULONG ulDecryptLength = DecryptLength(); + +// // nella decrypt il buffer deve essere lungo esasttamente k +// // (specifiche P11) +// if (baDecryptBuffer.size() != ulDecryptLength) +// throw p11_error(CKR_ENCRYPTED_DATA_LEN_RANGE); + +// return baDecryptBuffer; + +//} + +//ByteDynArray CRSA_X509::DecryptRemovePadding(ByteArray &paddedData) +//{ +// init_func +// // non faccio nullptra perchè l'RSA_X509 non leva il padding +// return paddedData; +//} + +/* ******************** */ +/* RSA_PKCS1 */ +/* ******************** */ +CRSA_PKCS1::CRSA_PKCS1(std::shared_ptr Session) : CSignRSA(CKM_RSA_PKCS, Session), + CSignRecoverRSA(CKM_RSA_PKCS, Session), + CVerifyRSA(CKM_RSA_PKCS, Session), + CVerifyRecoverRSA(CKM_RSA_PKCS, Session) /*, + CEncryptRSA(CKM_RSA_PKCS, Session), + CDecryptRSA(CKM_RSA_PKCS, Session) */ +{} +CRSA_PKCS1::~CRSA_PKCS1() {} + +void CRSA_PKCS1::VerifyInit(CK_OBJECT_HANDLE PublicKey) { + init_func + hVerifyKey = PublicKey; +} + +void CRSA_PKCS1::VerifyUpdate(ByteArray &Part) { + init_func + auto dwSize = baVerifyBuffer.size(); + baVerifyBuffer.resize(dwSize + Part.size(), true); + baVerifyBuffer.mid(dwSize, Part.size()).copy(Part); +} + +void CRSA_PKCS1::VerifyFinal(ByteArray &Signature) { + init_func + ByteDynArray baPlainSignature; + CK_ULONG ulVerifyLength = VerifyLength(); + + if (Signature.size() != ulVerifyLength) + throw p11_error(CKR_SIGNATURE_LEN_RANGE); + + // max k-11 (specifiche p11) + if (baVerifyBuffer.size() > ulVerifyLength - 11) + throw p11_error(CKR_DATA_LEN_RANGE); + + baPlainSignature = VerifyDecryptSignature(Signature); + + ByteDynArray baExpectedResult(ulVerifyLength); + baExpectedResult.rightcopy(baVerifyBuffer); + PutPaddingBT1(baExpectedResult, baVerifyBuffer.size()); + + if (baPlainSignature == baExpectedResult) + return; + else + throw p11_error(CKR_SIGNATURE_INVALID); +} + +void CRSA_PKCS1::VerifyRecoverInit(CK_OBJECT_HANDLE PublicKey) { + init_func + hVerifyRecoverKey = PublicKey; +} + +ByteDynArray CRSA_PKCS1::VerifyRecover(ByteArray &Signature) { + init_func + CK_ULONG ulVerifyRecoverLength = VerifyRecoverLength(); + + if (Signature.size() != ulVerifyRecoverLength) + throw p11_error(CKR_SIGNATURE_LEN_RANGE); + + ByteDynArray baPlainSignature = VerifyRecoverDecryptSignature(Signature); + + // se non posso levare il padding, la firma ha + // qualcosa di sbagliato + size_t dwPadLen; + try { + dwPadLen = RemovePaddingBT1(baPlainSignature); + } catch (...) { + throw p11_error(CKR_SIGNATURE_INVALID); + } + + // i dati restutuiti non possono essere più + // lunghi di k-11!! (specifiche p11) + auto Data = baPlainSignature.mid(dwPadLen); + if (Data.size() > ulVerifyRecoverLength - 11) + throw p11_error(CKR_DATA_LEN_RANGE); + return Data; +} + +void CRSA_PKCS1::SignInit(CK_OBJECT_HANDLE PrivateKey) { + init_func + hSignKey = PrivateKey; +} + +void CRSA_PKCS1::SignReset() { + init_func + baSignBuffer.clear(); +} + +void CRSA_PKCS1::SignUpdate(ByteArray &Part) { + init_func + auto dwSize = baSignBuffer.size(); + baSignBuffer.resize(dwSize + Part.size(), true); + baSignBuffer.mid(dwSize, Part.size()).copy(Part); +} + +ByteDynArray CRSA_PKCS1::SignFinal() { + init_func + CK_ULONG ulSignatureLength = SignLength(); + + // al massimo k-11 bytes (specifiche p11) + if (baSignBuffer.size() > ulSignatureLength - 11) + throw p11_error(CKR_DATA_LEN_RANGE); + + return baSignBuffer; +} + +void CRSA_PKCS1::SignRecoverInit(CK_OBJECT_HANDLE PrivateKey) { + init_func + hSignRecoverKey = PrivateKey; +} + +ByteDynArray CRSA_PKCS1::SignRecover(ByteArray &Data) { + init_func + + CK_ULONG ulSignatureLength = SignRecoverLength(); + + // al massimo k-11 bytes (specifiche p11) + if (Data.size() > ulSignatureLength - 11) + throw p11_error(CKR_DATA_LEN_RANGE); + + return Data; + +} +//void CRSA_PKCS1::EncryptInit(CK_OBJECT_HANDLE PublicKey) { +// init_func +// hEncryptKey = PublicKey; +//} + +//ByteDynArray CRSA_PKCS1::EncryptUpdate(ByteArray &Part) { +// init_func +// auto dwSize = baEncryptBuffer.size(); +// baEncryptBuffer.resize(dwSize + Part.size(), true); +// baEncryptBuffer.mid(dwSize, Part.size()).copy(Part); +// return ByteDynArray(); +//} + +//ByteDynArray CRSA_PKCS1::EncryptFinal() +//{ +// init_func +// CK_ULONG ulEncryptLength = EncryptLength(); + +// // al massimo k-11 bytes (specifiche p11) +// if (baEncryptBuffer.size() > (ulEncryptLength - 11)) +// throw p11_error(CKR_DATA_LEN_RANGE); + +// ByteDynArray baPlainData(ulEncryptLength); +// baPlainData.rightcopy(baEncryptBuffer); +// PutPaddingBT2(baPlainData, baEncryptBuffer.size()); + +// return EncryptCompute(baPlainData); + +//} + +//void CRSA_PKCS1::DecryptInit(CK_OBJECT_HANDLE PrivateKey) +//{ +// init_func +// hDecryptKey = PrivateKey; +//} + +//ByteDynArray CRSA_PKCS1::DecryptUpdate(ByteArray &Part) { +// init_func +// auto dwSize = baDecryptBuffer.size(); +// baDecryptBuffer.resize(dwSize + Part.size(), true); +// baDecryptBuffer.mid(dwSize, Part.size()).copy(Part); +// return ByteDynArray(); +//} + +//ByteDynArray CRSA_PKCS1::DecryptFinal() +//{ +// init_func +// CK_ULONG ulDecryptLength = DecryptLength(); + +// // esattamente k bytes (specifiche p11, ma mi sembra ovvio!) +// if (baDecryptBuffer.size() != ulDecryptLength) +// throw p11_error(CKR_ENCRYPTED_DATA_LEN_RANGE); + +// return baDecryptBuffer; +//} + +//ByteDynArray CRSA_PKCS1::DecryptRemovePadding(ByteArray &paddedData) +//{ +// init_func + +// // devo levare il padding BT2 da paddedData e copiare tutto in unpaddedData; +// // se non posso levare il padding i dati criptati non sono validi! +// size_t dwPaddingLen; +// try { +// dwPaddingLen = RemovePaddingBT2(paddedData); +// } +// catch (...) { +// throw p11_error(CKR_ENCRYPTED_DATA_INVALID); +// } + +// auto unpaddedData = paddedData.mid(dwPaddingLen); + +// // i dati possono essere lunghi al massiko k-11 +// // (specifiche p11) +// if (unpaddedData.size() > paddedData.size() - 11) +// throw p11_error(CKR_ENCRYPTED_DATA_INVALID); + +// return unpaddedData; +//} + +/* ************************ */ +/* SignRSA_withDigest */ +/* ************************ */ + +CSignRSAwithDigest::CSignRSAwithDigest(CK_MECHANISM_TYPE type, std::shared_ptr Session, CDigest *Digest) : pDigest(Digest), CSignRSA(type, std::move(Session)) {} +CSignRSAwithDigest::~CSignRSAwithDigest() {} + +bool CSignRSAwithDigest::SignSupportMultipart() { + init_func + return true; +} + +void CSignRSAwithDigest::SignInit(CK_OBJECT_HANDLE hPrivateKey) { + init_func + hSignKey = hPrivateKey; + pDigest->DigestInit(); +} + +void CSignRSAwithDigest::SignReset() { + init_func + pDigest->DigestInit(); +} + + +void CSignRSAwithDigest::SignUpdate(ByteArray &Part) { + init_func + pDigest->DigestUpdate(Part); +} + +ByteDynArray CSignRSAwithDigest::SignFinal() { + init_func + CK_ULONG ulDigestLength = pDigest->DigestLength(); + + ByteDynArray SignBuffer(ulDigestLength); + pDigest->DigestFinal(SignBuffer); + + ByteDynArray baDigestInfo = pDigest->DigestInfo(); + + return baDigestInfo.append(SignBuffer); +} + +ByteDynArray CSignRSAwithDigest::SignGetOperationState() { + init_func + return pDigest->DigestGetOperationState(); +} + +void CSignRSAwithDigest::SignSetOperationState(ByteArray &OperationState) { + init_func + pDigest->DigestSetOperationState(OperationState); +} + +/* ************************ */ +/* VerifyRSA_withDigest */ +/* ************************ */ + +CVerifyRSAwithDigest::CVerifyRSAwithDigest(CK_MECHANISM_TYPE type, std::shared_ptr Session, CDigest *Digest) : pDigest(Digest), CVerifyRSA(type, std::move(Session)) {} +CVerifyRSAwithDigest::~CVerifyRSAwithDigest() {} + +bool CVerifyRSAwithDigest::VerifySupportMultipart() { + init_func + return true; +} + +void CVerifyRSAwithDigest::VerifyInit(CK_OBJECT_HANDLE PublicKey) { + init_func + hVerifyKey = PublicKey; + pDigest->DigestInit(); +} + +void CVerifyRSAwithDigest::VerifyUpdate(ByteArray &Part) { + init_func + pDigest->DigestUpdate(Part); +} + +void CVerifyRSAwithDigest::VerifyFinal(ByteArray &Signature) { + init_func + ByteDynArray baPlainSignature; + CK_ULONG ulVerifyLength = VerifyLength(); + + if (Signature.size() != ulVerifyLength) + throw p11_error(CKR_SIGNATURE_LEN_RANGE); + + baPlainSignature = VerifyDecryptSignature(Signature); + + ByteDynArray baExpectedResult(ulVerifyLength); + CK_ULONG ulDigestLen = pDigest->DigestLength(); + ByteArray baDigestInfo = pDigest->DigestInfo(); + + ByteArray ba1 = baExpectedResult.right(ulDigestLen); + pDigest->DigestFinal(ba1); + baExpectedResult.rightcopy(baDigestInfo, ulDigestLen); + PutPaddingBT1(baExpectedResult, ulDigestLen + baDigestInfo.size()); + + if (baPlainSignature == baExpectedResult) + return; + else + throw p11_error(CKR_SIGNATURE_INVALID); +} + +ByteDynArray CVerifyRSAwithDigest::VerifyGetOperationState() { + init_func + return pDigest->DigestGetOperationState(); +} + +void CVerifyRSAwithDigest::VerifySetOperationState(ByteArray &OperationState) { + init_func + pDigest->DigestSetOperationState(OperationState); +} +/* ******************** */ +/* RSA_withMD5 */ +/* ******************** */ +CRSAwithMD5::CRSAwithMD5(std::shared_ptr Session) : CSignRSAwithDigest(CKM_MD5_RSA_PKCS, Session, &md5), CVerifyRSAwithDigest(CKM_MD5_RSA_PKCS, Session, &md5), md5(Session) {} +CRSAwithMD5::~CRSAwithMD5() {} + +/* ******************** */ +/* RSA_withSHA1 */ +/* ******************** */ +CRSAwithSHA1::CRSAwithSHA1(std::shared_ptr Session) : CSignRSAwithDigest(CKM_SHA1_RSA_PKCS, Session, &sha1), CVerifyRSAwithDigest(CKM_SHA1_RSA_PKCS, Session, &sha1), sha1(Session) {} +CRSAwithSHA1::~CRSAwithSHA1() {} + +/* ******************** */ +/* RSA_withSHA1 */ +/* ******************** */ +CRSAwithSHA256::CRSAwithSHA256(std::shared_ptr Session) : CSignRSAwithDigest(CKM_SHA256_RSA_PKCS, Session, &sha256), CVerifyRSAwithDigest(CKM_SHA256_RSA_PKCS, Session, &sha256), sha256(Session) {} +CRSAwithSHA256::~CRSAwithSHA256() {} + +///* ******************** */ +///* EncryptRSA */ +///* ******************** */ +//CEncryptRSA::CEncryptRSA(CK_MECHANISM_TYPE type, std::shared_ptr Session) : CEncrypt(type, std::move(Session)) {} +//CEncryptRSA::~CEncryptRSA() {} + +//bool CEncryptRSA::EncryptSupportMultipart() { +// init_func +// return false; +//} + +//CK_ULONG CEncryptRSA::EncryptLength() { +// init_func +// std::shared_ptr pObject = pSession->pSlot->GetObjectFromID(hEncryptKey); +// ER_ASSERT(pObject != nullptr, ERR_CANT_GET_OBJECT) +// ER_ASSERT(pObject->ObjClass == CKO_PUBLIC_KEY, ERR_WRONG_OBJECT_TYPE) +// auto pPrivateKey = std::static_pointer_cast(pObject); + +// ByteArray *baKeyModule = pPrivateKey->getAttribute(CKA_MODULUS); +// ER_ASSERT(baKeyModule != nullptr, ERR_CANT_GET_PUBKEY_MODULUS) +// return (CK_ULONG)baKeyModule->size(); +//} + +//ByteDynArray CEncryptRSA::EncryptCompute(ByteArray &baPlainData) +//{ +// init_func +// ByteArray *baKeyExponent = nullptr, *baKeyModule = nullptr; + +// std::shared_ptr pObject = pSession->pSlot->GetObjectFromID(hEncryptKey); +// ER_ASSERT(pObject != nullptr, ERR_CANT_GET_OBJECT) +// ER_ASSERT(pObject->ObjClass == CKO_PUBLIC_KEY, ERR_WRONG_OBJECT_TYPE) +// auto pPublicKey = std::static_pointer_cast(pObject); + +// baKeyExponent = pPublicKey->getAttribute(CKA_PUBLIC_EXPONENT); +// ER_ASSERT(baKeyExponent != nullptr, ERR_CANT_GET_PUBKEY_EXPONENT) + +// baKeyModule = pPublicKey->getAttribute(CKA_MODULUS); +// ER_ASSERT(baKeyModule != nullptr, ERR_CANT_GET_PUBKEY_MODULUS) + +// auto dwKeyLenBytes = baKeyModule->size(); + +// // è molto strano che baPlainData non sia lungo quanto la chiave... +// // il controllo su CKR_DATA_LEN_RANGE è stato fatto prima, ma +// // lo uso anche in questo caso +// if (baPlainData.size() != dwKeyLenBytes) +// throw p11_error(CKR_DATA_LEN_RANGE); + +// CRSA rsa(*baKeyModule, *baKeyExponent); +// return rsa.RSA_PURE(baPlainData); +//} + +//ByteDynArray CEncryptRSA::EncryptGetOperationState() +//{ +// init_func +// return ByteDynArray(); +//} + +//void CEncryptRSA::EncryptSetOperationState(ByteArray &OperationState) +//{ +// init_func +// if (OperationState.size() != 0) +// throw p11_error(CKR_SAVED_STATE_INVALID); +//} + +/* ******************** */ +/* DecryptRSA */ +/* ******************** */ +//CDecryptRSA::CDecryptRSA() {} +/*CDecryptRSA::CDecryptRSA(CK_MECHANISM_TYPE type, std::shared_ptr Session) : CDecrypt(type, std::move(Session)) {} +CDecryptRSA::~CDecryptRSA() {} + +bool CDecryptRSA::DecryptSupportMultipart() { + init_func + return false; +} + +CK_ULONG CDecryptRSA::DecryptLength() { + init_func + std::shared_ptr pObject = pSession->pSlot->GetObjectFromID(hDecryptKey); + ER_ASSERT(pObject != nullptr, ERR_CANT_GET_OBJECT) + ER_ASSERT(pObject->ObjClass == CKO_PRIVATE_KEY, ERR_WRONG_OBJECT_TYPE) + auto pPrivateKey = std::static_pointer_cast(pObject); + + ByteArray *baKeyModule = pPrivateKey->getAttribute(CKA_MODULUS); + ER_ASSERT(baKeyModule != nullptr, ERR_CANT_GET_PUBKEY_MODULUS) + return (CK_ULONG)baKeyModule->size(); +} + +ByteDynArray CDecryptRSA::DecryptGetOperationState() +{ + init_func + return ByteDynArray(); +} + +void CDecryptRSA::DecryptSetOperationState(ByteArray &OperationState) +{ + init_func + if (OperationState.size() != 0) + throw p11_error(CKR_SAVED_STATE_INVALID); +}*/ + +} diff --git a/libcie-pkcs11/PKCS11/P11Object.cpp b/libcie-pkcs11/PKCS11/P11Object.cpp index 2b9dd43a..2f9a7891 100644 --- a/libcie-pkcs11/PKCS11/P11Object.cpp +++ b/libcie-pkcs11/PKCS11/P11Object.cpp @@ -1,163 +1,163 @@ - -#include "P11Object.h" -#include "CardTemplate.h" - -extern CLog Log; - - -namespace p11 { - -CP11Object::CP11Object(CK_OBJECT_CLASS objClass,void *TemplateData) { - ObjClass=objClass; - pTemplateData=TemplateData; - addAttribute(CKA_CLASS,ByteArray((BYTE*)&ObjClass,sizeof(CK_OBJECT_CLASS))); -} - -void CP11Object::addAttribute(CK_ATTRIBUTE_TYPE type,ByteArray data) { - init_func - attributes[type] = data; -} - -ByteArray* CP11Object::getAttribute(CK_ATTRIBUTE_TYPE type) { - init_func - AttributeMap::const_iterator pPair; - pPair=attributes.find(type); - if (pPair==attributes.end()) { - return nullptr; - } - return (ByteArray*)&pPair->second; -} - -CK_ULONG CP11Object::GetAttributeValue(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { - init_func - - bool attribInvalid = false; - - for (unsigned int i=0; isize(); - } else { - if (attr->size() > ulValLen) - throw p11_error(CKR_BUFFER_TOO_SMALL); - - ByteArray((uint8_t*)pTemplate[i].pValue, attr->size()).copy(*attr); - pTemplate[i].ulValueLen = (CK_ULONG)attr->size(); - } - } else { - pTemplate[i].ulValueLen = -1; - attribInvalid = true; - } - } - - return attribInvalid ? CKR_ATTRIBUTE_TYPE_INVALID : CKR_OK; -} - -CK_ULONG CP11Object::GetObjectSize() { - init_func - // devo almeno leggerlo dalla carta per sapere che dimensioni ha - if (!bReadValue) { - pSlot->pTemplate->FunctionList.templateReadObjectAttributes(pSlot->pTemplateData, this); - } - return pSlot->pTemplate->FunctionList.templateGetObjectSize(pSlot->pTemplateData,this); -} - -void CP11Object::SetAttributes(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { - init_func - for (DWORD i=0; ipTemplate->FunctionList.templateReadObjectAttributes(pSlot->pTemplateData, this); - } - - return CP11Object::getAttribute(type); -} - -CP11Data::CP11Data(void *TemplateData) : CP11Object(CKO_DATA,TemplateData) { - bReadValue=false; -} - -ByteArray* CP11Data::getAttribute(CK_ATTRIBUTE_TYPE type) { - init_func - AttributeMap::iterator it=attributes.find(type); - if (it==attributes.end() && !bReadValue) { - pSlot->pTemplate->FunctionList.templateReadObjectAttributes(pSlot->pTemplateData, this); - } - - return CP11Object::getAttribute(type); -} - -void CP11Data::SetAttributes(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { - init_func - CP11Object::SetAttributes(pTemplate, ulCount); - bReadValue = true; -} - -bool CP11Object::IsPrivate() { - init_func - ByteArray* baVal = getAttribute(CKA_PRIVATE); - - if (baVal==nullptr) - return false; - else - return (ByteArrayToVar(*baVal, CK_BBOOL) == TRUE); -} - -CP11PrivateKey::CP11PrivateKey(void *TemplateData) : CP11Object(CKO_PRIVATE_KEY,TemplateData) { - bReadValue=false; -} - -ByteArray* CP11PrivateKey::getAttribute(CK_ATTRIBUTE_TYPE type) { - init_func - - if (type==CKA_PRIME_1 || - type==CKA_PRIME_2 || - type==CKA_EXPONENT_1 || - type==CKA_EXPONENT_2 || - type==CKA_COEFFICIENT || - type==CKA_PRIME_1) - throw p11_error(CKR_ATTRIBUTE_SENSITIVE); - - AttributeMap::iterator it=attributes.find(type); - if (it==attributes.end() && !bReadValue) { - pSlot->pTemplate->FunctionList.templateReadObjectAttributes(pSlot->pTemplateData, this); - } - - return CP11Object::getAttribute(type); -} - -CP11PublicKey::CP11PublicKey(void *TemplateData) : CP11Object(CKO_PUBLIC_KEY,TemplateData) { - bReadValue=false; -} - -ByteArray* CP11PublicKey::getAttribute(CK_ATTRIBUTE_TYPE type) { - init_func - - AttributeMap::iterator it=attributes.find(type); - if (it==attributes.end() && !bReadValue) { - pSlot->pTemplate->FunctionList.templateReadObjectAttributes(pSlot->pTemplateData, this); - } - - return CP11Object::getAttribute(type); -} - -} + +#include "P11Object.h" +#include "CardTemplate.h" + +extern CLog Log; + + +namespace p11 { + +CP11Object::CP11Object(CK_OBJECT_CLASS objClass,void *TemplateData) { + ObjClass=objClass; + pTemplateData=TemplateData; + addAttribute(CKA_CLASS,ByteArray((BYTE*)&ObjClass,sizeof(CK_OBJECT_CLASS))); +} + +void CP11Object::addAttribute(CK_ATTRIBUTE_TYPE type,ByteArray data) { + init_func + attributes[type] = data; +} + +ByteArray* CP11Object::getAttribute(CK_ATTRIBUTE_TYPE type) { + init_func + AttributeMap::const_iterator pPair; + pPair=attributes.find(type); + if (pPair==attributes.end()) { + return nullptr; + } + return (ByteArray*)&pPair->second; +} + +CK_ULONG CP11Object::GetAttributeValue(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { + init_func + + bool attribInvalid = false; + + for (unsigned int i=0; isize(); + } else { + if (attr->size() > ulValLen) + throw p11_error(CKR_BUFFER_TOO_SMALL); + + ByteArray((uint8_t*)pTemplate[i].pValue, attr->size()).copy(*attr); + pTemplate[i].ulValueLen = (CK_ULONG)attr->size(); + } + } else { + pTemplate[i].ulValueLen = -1; + attribInvalid = true; + } + } + + return attribInvalid ? CKR_ATTRIBUTE_TYPE_INVALID : CKR_OK; +} + +CK_ULONG CP11Object::GetObjectSize() { + init_func + // devo almeno leggerlo dalla carta per sapere che dimensioni ha + if (!bReadValue) { + pSlot->pTemplate->FunctionList.templateReadObjectAttributes(pSlot->pTemplateData, this); + } + return pSlot->pTemplate->FunctionList.templateGetObjectSize(pSlot->pTemplateData,this); +} + +void CP11Object::SetAttributes(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { + init_func + for (DWORD i=0; ipTemplate->FunctionList.templateReadObjectAttributes(pSlot->pTemplateData, this); + } + + return CP11Object::getAttribute(type); +} + +CP11Data::CP11Data(void *TemplateData) : CP11Object(CKO_DATA,TemplateData) { + bReadValue=false; +} + +ByteArray* CP11Data::getAttribute(CK_ATTRIBUTE_TYPE type) { + init_func + AttributeMap::iterator it=attributes.find(type); + if (it==attributes.end() && !bReadValue) { + pSlot->pTemplate->FunctionList.templateReadObjectAttributes(pSlot->pTemplateData, this); + } + + return CP11Object::getAttribute(type); +} + +void CP11Data::SetAttributes(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { + init_func + CP11Object::SetAttributes(pTemplate, ulCount); + bReadValue = true; +} + +bool CP11Object::IsPrivate() { + init_func + ByteArray* baVal = getAttribute(CKA_PRIVATE); + + if (baVal==nullptr) + return false; + else + return (ByteArrayToVar(*baVal, CK_BBOOL) == TRUE); +} + +CP11PrivateKey::CP11PrivateKey(void *TemplateData) : CP11Object(CKO_PRIVATE_KEY,TemplateData) { + bReadValue=false; +} + +ByteArray* CP11PrivateKey::getAttribute(CK_ATTRIBUTE_TYPE type) { + init_func + + if (type==CKA_PRIME_1 || + type==CKA_PRIME_2 || + type==CKA_EXPONENT_1 || + type==CKA_EXPONENT_2 || + type==CKA_COEFFICIENT || + type==CKA_PRIME_1) + throw p11_error(CKR_ATTRIBUTE_SENSITIVE); + + AttributeMap::iterator it=attributes.find(type); + if (it==attributes.end() && !bReadValue) { + pSlot->pTemplate->FunctionList.templateReadObjectAttributes(pSlot->pTemplateData, this); + } + + return CP11Object::getAttribute(type); +} + +CP11PublicKey::CP11PublicKey(void *TemplateData) : CP11Object(CKO_PUBLIC_KEY,TemplateData) { + bReadValue=false; +} + +ByteArray* CP11PublicKey::getAttribute(CK_ATTRIBUTE_TYPE type) { + init_func + + AttributeMap::iterator it=attributes.find(type); + if (it==attributes.end() && !bReadValue) { + pSlot->pTemplate->FunctionList.templateReadObjectAttributes(pSlot->pTemplateData, this); + } + + return CP11Object::getAttribute(type); +} + +} diff --git a/libcie-pkcs11/PKCS11/PKCS11Functions.cpp b/libcie-pkcs11/PKCS11/PKCS11Functions.cpp index 27586d09..e6f3552e 100644 --- a/libcie-pkcs11/PKCS11/PKCS11Functions.cpp +++ b/libcie-pkcs11/PKCS11/PKCS11Functions.cpp @@ -1,2179 +1,2190 @@ -// P11Emissione.cpp : Defines the entry point for the DLL application. -// -#include -#include -#include -#include "wintypes.h" -#include "PKCS11Functions.h" -#include "InitP11.h" -#ifdef WIN32 -#include -#else -#include -#endif -#include "session.h" -#include "CardTemplate.h" -#ifdef WIN32 -#include -#else -#include -#endif -#include "../Util/ModuleInfo.h" -#include "../Util/util.h" -#include "../Util/SyncroEvent.h" -#include - -#include -#include "../Util/UUCByteArray.h" - -CLog Log; - -// flag: P11 inizializzato -bool bP11Initialized=false; -bool bP11Terminate=false; - -using namespace p11; - -std::mutex p11Mutex; -auto_reset_event p11slotEvent/*("CardOS_P11_Event")*/; - -// meccanismi supportati - - -CK_MECHANISM_TYPE P11mechanisms[]= { - //CKM_RSA_PKCS_KEY_PAIR_GEN, - CKM_RSA_PKCS, - CKM_MD5, - CKM_SHA_1, - CKM_SHA256, - CKM_SHA1_RSA_PKCS, - CKM_SHA256_RSA_PKCS, - CKM_MD5_RSA_PKCS -}; - - -char *getAttributeName(unsigned long dwId); -//extern CModuleInfo moduleInfo; // informazioni sulla dll (o so) -bool bModuleInit=false; - -#ifdef WIN32 -// funzione DllMain -// inizilizzo moduleInfo -BOOL APIENTRY DllMainP11( HANDLE hModule, - DWORD ul_reason_for_call, - LPVOID lpReserved - ) { - if (ul_reason_for_call==DLL_PROCESS_ATTACH && !bModuleInit) { - bModuleInit=true; - moduleInfo.init(hModule); - std::string mainMutexName; - //mainMutexName="CIE_P11_Mutex_"+moduleInfo.szModuleName; - //p11Mutex.Create(mainMutexName.c_str()); - //xmlInit(); - std::string configPath; - configPath = moduleInfo.szModulePath + moduleInfo.szModuleName + ".ini"; - initLog(configPath.c_str(), __DATE__ " " __TIME__); - Log.initModule("PKCS11", __DATE__ " " __TIME__); - p11::InitP11(configPath.c_str()); - - } - - if (ul_reason_for_call==DLL_PROCESS_DETACH && bModuleInit) { - - if (bP11Initialized) { - Log.write("%s","Forzatura C_Finalize"); - C_Finalize(NULL); - bP11Initialized = false; - } - //xmlCleanup(); - bModuleInit=false; - bP11Terminate=true; - - CSlot::DeleteSlotList(); - CCardTemplate::DeleteTemplateList(); - p11slotEvent.set(); - - } - - return TRUE; -} - -#else - -/* ---- GENERATE CK_FUNCTION_LIST */ - -#define CK_PKCS11_FUNCTION_INFO(name) \ -name, -// -//CK_FUNCTION_LIST pkcs11_function_list = { -// { LIBRARY_VERSION_MAJOR, LIBRARY_VERSION_MINOR }, -//#include "pkcs11f.h" -//}; -#undef CK_PKCS11_FUNCTION_INFO - - -__attribute__((constructor)) void DllMainAttach() { - // code - const char *homedir; - if ((homedir = getenv("HOME")) == NULL) { - homedir = getpwuid(getuid())->pw_dir; - } - bModuleInit=true; - std::string configPath = std::string(homedir) + "/.CIEPKI/ciepki.ini"; - initLog("CIEPKC11", configPath.c_str(), __DATE__ " " __TIME__); - p11::InitP11(configPath.c_str()); -} - -__attribute__((destructor)) void DllMainDetach() { - Log.write("%s","DllMainDetach"); - - if (bP11Initialized) { - Log.write("%s","Forzatura C_Finalize"); - C_Finalize(NULL); - bP11Initialized = false; - - CSlot::DeleteSlotList(); - CCardTemplate::DeleteTemplateList(); - try { - p11slotEvent.set(); - } catch(...) { - printf("event set error"); - } - } - - //xmlCleanup(); - bModuleInit=false; - bP11Terminate=true; -} - -#endif - -void WriteAttributes(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { - Log.write("Attributes: %x", ulCount); - for(unsigned int i = 0; i < ulCount; i++) { - if(pTemplate[i].pValue) { - switch(pTemplate[i].type) { - case CKA_CLASS: - Log.writePure("%d) type=%x (%s), value=%x, len=%x", i + 1, pTemplate[i].type, getAttributeName(pTemplate[i].type), *(CK_OBJECT_CLASS_PTR)(pTemplate[i].pValue), pTemplate[i].ulValueLen); - break; - - case CKA_TOKEN: - case CKA_PRIVATE: - case CKA_MODIFIABLE: - Log.writePure("%d) type=%x (%s), value=%x, len=%x", i + 1, pTemplate[i].type, getAttributeName(pTemplate[i].type), *(CK_BBOOL*)(pTemplate[i].pValue), pTemplate[i].ulValueLen); - break; - - case CKA_LABEL: - case CKA_OBJECT_ID: - Log.writePure("%d) type=%x (%s), value=%s, len=%x", i + 1, pTemplate[i].type, getAttributeName(pTemplate[i].type), (char*)(pTemplate[i].pValue), pTemplate[i].ulValueLen); - break; - - case CKA_VALUE: - Log.writePure("%d) type=%x (%s), value=%s, len=%x", i + 1, pTemplate[i].type, getAttributeName(pTemplate[i].type), UUCByteArray((BYTE*)pTemplate[i].pValue, pTemplate[i].ulValueLen).toHexString(), pTemplate[i].ulValueLen); - break; - - default: - Log.writePure("%d) type=%x (%s), value=%p, len=%x", i + 1, pTemplate[i].type, getAttributeName(pTemplate[i].type), pTemplate[i].pValue, pTemplate[i].ulValueLen); - break; - } - } else { - switch(pTemplate[i].type) { - case CKA_CLASS: - Log.writePure("%d) type=%x (%s), value=NULL, len=%x", i + 1, pTemplate[i].type, getAttributeName(pTemplate[i].type), pTemplate[i].ulValueLen); - break; - - case CKA_TOKEN: - case CKA_PRIVATE: - case CKA_MODIFIABLE: - Log.writePure("%d) type=%x (%s), value=NULL, len=%x", i + 1, pTemplate[i].type, getAttributeName(pTemplate[i].type), pTemplate[i].ulValueLen); - break; - - case CKA_LABEL: - case CKA_OBJECT_ID: - Log.writePure("%d) type=%x (%s), value=NULL, len=%x", i + 1, pTemplate[i].type, getAttributeName(pTemplate[i].type), pTemplate[i].ulValueLen); - break; - - default: - Log.writePure("%d) type=%x (%s), value=NULL, len=%x", i + 1, pTemplate[i].type, getAttributeName(pTemplate[i].type), pTemplate[i].ulValueLen); - break; - } - } - } -} - -void WriteMechanism(CK_MECHANISM_PTR pMechanism) { - Log.write("Mechanism : %x", pMechanism->mechanism); - Log.write("Parameter: %x", pMechanism->pParameter); - Log.write("Parameter len: %x", pMechanism->ulParameterLen); -} - -// funzione CheckMechanismParam -bool CheckMechanismParam(CK_MECHANISM *pParam) { - init_func - // tutti i mechanism non hanno parametri - if (pParam->pParameter==NULL && pParam->ulParameterLen==0) { - return true; - } - return false; -} - -CK_RV CK_ENTRY C_UpdateSlotList() { - init_p11_func - std::unique_lock lock(p11Mutex); - - CSlot::InitSlotList(); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_AbilitaCIE(const char* szPAN, const char* szPIN) { //, PROGRESS_CALLBACK progressCallBack) - return 0; -} - -CK_RV CK_ENTRY C_GetSlotList(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkOutArray(pSlotList, pulCount) - - logParam(tokenPresent) - logParam(pSlotList) - logParam(pulCount) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - bool bOver=false; - std::vector slotsRet; - unsigned int iCnt; - if (tokenPresent) { - // solo i lettori con la carta inserita - iCnt=0; - - if (CSlot::g_mSlots.size()==0) { - *pulCount=0; - return CKR_OK; - - } - SlotMap::const_iterator it=CSlot::g_mSlots.end(); - do { - it--; - std::shared_ptr pSlot=it->second; - - if (pSlot->IsTokenPresent()) { - if (pSlotList) { - if (iCnt<*pulCount) - pSlotList[iCnt]=pSlot->hSlot; - else - bOver=true; - } - iCnt++; - } - } while (it!=CSlot::g_mSlots.begin()); - } else { - // restituisco tutti i lettori - if (!pSlotList) { - iCnt=(CK_ULONG)CSlot::g_mSlots.size(); - } else { - iCnt=0; - SlotMap::const_iterator it=CSlot::g_mSlots.end(); - while (it!=CSlot::g_mSlots.begin()) { - it--; - if (iCnt<*pulCount) - pSlotList[iCnt]=it->first; - else - bOver=true; - iCnt++; - } - } - } - *pulCount=iCnt; - if (bOver) - throw p11_error(CKR_BUFFER_TOO_SMALL); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_Initialize(CK_VOID_PTR pReserved) { - init_p11_func - std::unique_lock lock(p11Mutex); - - logParam(pReserved) - -// CK_C_INITIALIZE_ARGS_PTR ptr=(CK_C_INITIALIZE_ARGS_PTR)pReserved; - - if (bP11Initialized) - return CKR_OK; - // throw p11_error(CKR_CRYPTOKI_ALREADY_INITIALIZED) - - // verifico che i flag siano supportati - CK_C_INITIALIZE_ARGS_PTR iargs = NULL_PTR; - if (pReserved) { - iargs = (CK_C_INITIALIZE_ARGS_PTR)pReserved; - if (iargs->pReserved != NULL) - throw p11_error(CKR_ARGUMENTS_BAD); - - if (iargs->flags & CKF_OS_LOCKING_OK) { - if ((iargs->CreateMutex) || (iargs->DestroyMutex) || (iargs->LockMutex) || (iargs->UnlockMutex)) - throw p11_error(CKR_CANT_LOCK); - } else if (iargs->flags == 0) { - if ((iargs->CreateMutex) || (iargs->DestroyMutex) || (iargs->LockMutex) || (iargs->UnlockMutex)) - throw p11_error(CKR_CANT_LOCK); - } else if (iargs->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) - throw p11_error(CKR_NEED_TO_CREATE_THREADS); - else - throw p11_error(CKR_ARGUMENTS_BAD); - } - - - if (CCardTemplate::g_mCardTemplates.size()==0) - CCardTemplate::InitTemplateList(); - - bP11Initialized = true; - - CSlot::InitSlotList(); - - Log.write("C_Initialize ok"); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_Finalize(CK_VOID_PTR pReserved) { - init_p11_func - std::unique_lock lock(p11Mutex); - - logParam(pReserved) - - if (pReserved != NULL) - throw p11_error(CKR_ARGUMENTS_BAD); - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - bP11Initialized = false; - - // TODO verificare thread "vuoto" - if (CSlot::Thread.joinable()) { - CCardContext *tc = CSlot::ThreadContext; - if (tc != nullptr) { - SCARDCONTEXT hC = tc->hContext; - if (hC) - SCardCancel(hC); - } - p11Mutex.unlock(); - CSlot::Thread.join(); - p11Mutex.lock(); - } - - - for(SlotMap::const_iterator it=CSlot::g_mSlots.begin(); it!=CSlot::g_mSlots.end(); it++) { - it->second->CloseAllSessions(); - } - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, CK_NOTIFY notify, CK_SESSION_HANDLE_PTR phSession) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkOutPtr(phSession) - - logParam(slotID) - logParam(flags) - logParam(pApplication) - logParam(notify) - logParam(phSession) - - - - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - if (!(flags & CKF_SERIAL_SESSION)) - throw p11_error(CKR_SESSION_PARALLEL_NOT_SUPPORTED); - - std::shared_ptr pSlot = CSlot::GetSlotFromID(slotID); - if (pSlot == nullptr) - throw p11_error(CKR_SLOT_ID_INVALID); - - auto pSession = std::unique_ptr(new CSession()); - pSession->pSlot=pSlot; - pSession->flags=flags; - pSession->notify=notify; - pSession->pApplication=pApplication; - - if ((flags & CKF_RW_SESSION)==0) { - // se una sessione RO devo - // verificare che non ci siano sessioni SO RW - if (pSession->ExistsSO_RW()) - throw p11_error(CKR_SESSION_READ_WRITE_SO_EXISTS); - } - - pSlot->Init(); - - pSession->slotID=slotID; - -// aggiungo la sessione all'elenco globale - *phSession = CSession::AddSession(std::move(pSession)); - - if (Log.Enabled) { - Log.writePure("Sessione: %i",*phSession); - Log.writePure("Lettore: %s",pSlot->szName.c_str()); - Log.writePure("CardManager: %s",pSlot->pTemplate->szName.c_str()); - std::string szModel; - pSlot->pTemplate->FunctionList.templateGetModel(*pSlot,szModel); - Log.writePure("Tipo Carta: %s",szModel.c_str()); - } - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkOutPtr(pInfo) - - logParam(slotID) - logParam(pInfo) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSlot = CSlot::GetSlotFromID(slotID); - - if (pSlot == nullptr) - throw p11_error(CKR_SLOT_ID_INVALID); - - if (pInfo == nullptr) - throw p11_error(CKR_ARGUMENTS_BAD); - - if (!pSlot->IsTokenPresent()) - throw p11_error(CKR_TOKEN_NOT_PRESENT); - - pSlot->GetTokenInfo(pInfo); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_CloseSession(CK_SESSION_HANDLE hSession) { - init_p11_func - std::unique_lock lock(p11Mutex); - - logParam(hSession) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession = CSession::GetSessionFromID(hSession); - - if (pSession==nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - CSession::DeleteSession(hSession); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_CloseAllSessions(CK_SLOT_ID slotID) { - init_p11_func - std::unique_lock lock(p11Mutex); - - logParam(slotID) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSlot = CSlot::GetSlotFromID(slotID); - - if (pSlot==nullptr) - throw p11_error(CKR_SLOT_ID_INVALID); - - pSlot->CloseAllSessions(); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - - -CK_RV CK_ENTRY C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkOutPtr(pInfo) - - logParam(slotID) - logParam(pInfo) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSlot = CSlot::GetSlotFromID(slotID); - if (pSlot==NULL) - throw p11_error(CKR_SLOT_ID_INVALID); - - if (pInfo == NULL) - throw p11_error(CKR_ARGUMENTS_BAD); - - pSlot->GetInfo(pInfo); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_GetInfo(CK_INFO_PTR pInfo /* location that receives information */) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkOutPtr(pInfo) - - logParam(pInfo) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - pInfo->cryptokiVersion.major = 2; /* Cryptoki interface ver */ - pInfo->cryptokiVersion.minor = 10; //12345678901234567890123456789012 - CryptoPP::memcpy_s((char*)pInfo->manufacturerID,32,"IPZS\0 ", 32); - - pInfo->flags = 0; /* must be zero */ - - /* libraryDescription and libraryVersion are new for v2.0 */ - CryptoPP::memcpy_s((char*)pInfo->libraryDescription,32,"CIE PKCS11\0 ", 32); - - pInfo->libraryVersion.major = 1; /* version of library */ - pInfo->libraryVersion.minor = 0; /* version of library */ - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkOutPtr(ppFunctionList) - - logParam(ppFunctionList) - - if (ppFunctionList == NULL) - throw p11_error(CKR_ARGUMENTS_BAD); - - static CK_FUNCTION_LIST functionList = {{ 2, 20}, - C_Initialize, - C_Finalize, - C_GetInfo, - C_GetFunctionList, - C_GetSlotList, - C_GetSlotInfo, - C_GetTokenInfo, - C_GetMechanismList, - C_GetMechanismInfo, - C_InitToken, - C_InitPIN, - C_SetPIN, - C_OpenSession, - C_CloseSession, - C_CloseAllSessions, - C_GetSessionInfo, - C_GetOperationState, - C_SetOperationState, - C_Login, - C_Logout, - C_CreateObject, - C_CopyObject, - C_DestroyObject, - C_GetObjectSize, - C_GetAttributeValue, - C_SetAttributeValue, - C_FindObjectsInit, - C_FindObjects, - C_FindObjectsFinal, - C_EncryptInit, - C_Encrypt, - C_EncryptUpdate, - C_EncryptFinal, - C_DecryptInit, - C_Decrypt, - C_DecryptUpdate, - C_DecryptFinal, - C_DigestInit, - C_Digest, - C_DigestUpdate, C_DigestKey, C_DigestFinal, C_SignInit, C_Sign, - C_SignUpdate, C_SignFinal, C_SignRecoverInit, C_SignRecover, - C_VerifyInit, C_Verify, C_VerifyUpdate, C_VerifyFinal, - C_VerifyRecoverInit, C_VerifyRecover, C_DigestEncryptUpdate, - C_DecryptDigestUpdate, C_SignEncryptUpdate, C_DecryptVerifyUpdate, - C_GenerateKey, C_GenerateKeyPair, C_WrapKey, C_UnwrapKey, - C_DeriveKey, C_SeedRandom, C_GenerateRandom, C_GetFunctionStatus, - C_CancelFunction, C_WaitForSlotEvent - }; - - *ppFunctionList = &functionList; - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_CreateObject(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject) { - init_p11_func - std::unique_lock lock(p11Mutex); - - -// checkOutPtr(phObject) - - logParam(hSession) - logParam(pTemplate) - logParam(ulCount) - logParam(phObject) - - WriteAttributes(pTemplate, ulCount); - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession = CSession::GetSessionFromID(hSession); - - if (pSession==nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - *phObject = pSession->CreateObject(pTemplate, ulCount); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_GenerateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkInPtr(pMechanism) -// checkOutPtr(phKey) - - logParam(hSession) - logParam(pMechanism) - logParam(pTemplate) - logParam(ulCount) - logParam(phKey) - - WriteAttributes(pTemplate, ulCount); - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession = CSession::GetSessionFromID(hSession); - - if (pSession == nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - *phKey = pSession->GenerateKey(pMechanism, pTemplate, ulCount); - return CKR_OK; - - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_GenerateKeyPair(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkInPtr(pMechanism) -// checkOutPtr(phPublicKey) -// checkOutPtr(phPrivateKey) - - logParam(hSession) - logParam(pMechanism) - logParam(pPublicKeyTemplate) - logParam(pPrivateKeyTemplate) - logParam(ulPublicKeyAttributeCount) - logParam(ulPrivateKeyAttributeCount) - logParam(phPublicKey) - logParam(phPrivateKey) - - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession = CSession::GetSessionFromID(hSession); - - if (pSession==nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - pSession->GenerateKeyPair(pMechanism, pPublicKeyTemplate, ulPublicKeyAttributeCount, pPrivateKeyTemplate, ulPrivateKeyAttributeCount, phPublicKey, phPrivateKey); - return CKR_OK; - - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_DestroyObject(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject) { - init_p11_func - std::unique_lock lock(p11Mutex); - - logParam(hSession) - logParam(hObject) - - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession = CSession::GetSessionFromID(hSession); - - if (pSession == nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - pSession->DestroyObject(hObject); - return CKR_OK; - - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_DigestInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkInPtr(pMechanism) - - logParam(hSession) - logParam(pMechanism) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession = CSession::GetSessionFromID(hSession); - if (pSession==nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - if (!CheckMechanismParam(pMechanism)) - throw p11_error(CKR_MECHANISM_PARAM_INVALID); - - pSession->DigestInit(pMechanism); - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_Digest(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkInBuffer(pData, ulDataLen) -// checkOutArray(pDigest, pulDigestLen) - - logParam(hSession) - logParamBuf(pData, ulDataLen) - logParamBuf(pDigest, pulDigestLen) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession = CSession::GetSessionFromID(hSession); - - if (pSession == nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - ByteArray Digest(pDigest, *pulDigestLen); - ByteArray input(pData, ulDataLen); - pSession->Digest(input, Digest); - *pulDigestLen = (CK_ULONG)Digest.size(); - -// ByteDynArray Digest = ByteArray(pDigest, *pulDigestLen); -// ByteArray input(pData, ulDataLen); -// pSession->Digest(input, Digest); -// *pulDigestLen = (CK_ULONG)Digest.size(); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_DigestFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkOutArray(pDigest, pulDigestLen) - - logParam(hSession) - logParamBuf(pDigest, pulDigestLen) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession = CSession::GetSessionFromID(hSession); - - if (pSession==nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - ByteDynArray Digest = ByteArray(pDigest, *pulDigestLen); - pSession->DigestFinal(Digest); - *pulDigestLen = (CK_ULONG)Digest.size(); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_DigestUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkInBuffer(pPart, ulPartLen) - - logParam(hSession) - logParamBuf(pPart, ulPartLen) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession = CSession::GetSessionFromID(hSession); - if (pSession==nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - ByteArray input(pPart, ulPartLen); - pSession->DigestUpdate(input); - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_FindObjects(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE_PTR phObject,CK_ULONG ulMaxObjectCount,CK_ULONG_PTR pulObjectCount) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkOutBuffer(phObject, sizeof(CK_OBJECT_HANDLE)*ulMaxObjectCount) - - logParam(hSession) - logParam(phObject) - logParam(ulMaxObjectCount) - logParam(pulObjectCount) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession = CSession::GetSessionFromID(hSession); - if (pSession == nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - if (phObject == NULL && ulMaxObjectCount > 0) - throw p11_error(CKR_ARGUMENTS_BAD); - - pSession->FindObjects(phObject, ulMaxObjectCount, pulObjectCount); - - Log.write("Objects found: %d", *pulObjectCount); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_FindObjectsFinal(CK_SESSION_HANDLE hSession) { - init_p11_func - std::unique_lock lock(p11Mutex); - - logParam(hSession) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession = CSession::GetSessionFromID(hSession); - if (pSession==nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - pSession->FindObjectsFinal(); - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} -CK_RV CK_ENTRY C_FindObjectsInit(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkInArray(pTemplate,ulCount) - - logParam(hSession) - logParam(pTemplate) - logParam(ulCount) - - WriteAttributes(pTemplate, ulCount); - -// if (Log.LogParam) { -// for (DWORD i=0;i pSession = CSession::GetSessionFromID(hSession); - if (pSession == nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - if (pTemplate == NULL && ulCount > 0) - throw p11_error(CKR_ARGUMENTS_BAD); - - pSession->FindObjectsInit(pTemplate, ulCount); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_GetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkInArray(pTemplate, ulCount) - - logParam(hSession) - logParam(hObject) - logParam(pTemplate) - logParam(ulCount) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession = CSession::GetSessionFromID(hSession); - if (pSession==nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - Log.write("In template"); - WriteAttributes(pTemplate, ulCount); - - CK_RV rv = pSession->GetAttributeValue(hObject, pTemplate, ulCount); - -// if (Log.LogParam) { -// for (DWORD i=0;i lock(p11Mutex); - -// checkOutArray(pMechanismList,pulCount) - - logParam(slotID) - logParam(pMechanismList) - logParam(pulCount) - - DWORD dwNumMechansms=sizeof(P11mechanisms)/sizeof(CK_MECHANISM_TYPE); - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSlot = CSlot::GetSlotFromID(slotID); - if (pSlot == nullptr) - throw p11_error(CKR_SLOT_ID_INVALID); - - if (pMechanismList == nullptr) { - *pulCount = dwNumMechansms; - return CKR_OK; - } - - if (*pulCount >= dwNumMechansms) { - CryptoPP::memcpy_s(pMechanismList, dwNumMechansms * sizeof(CK_MECHANISM_TYPE), P11mechanisms, dwNumMechansms * sizeof(CK_MECHANISM_TYPE)); - return CKR_OK; - } else - throw p11_error(CKR_BUFFER_TOO_SMALL); - - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo) { - init_p11_func - std::unique_lock lock(p11Mutex); - - logParam(slotID) - logParam(type) - logParam(pInfo) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSlot=CSlot::GetSlotFromID(slotID); - - if (pSlot == nullptr) - throw p11_error(CKR_SLOT_ID_INVALID); - - switch (type) { - case CKM_RSA_PKCS: - pInfo->flags = CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_SIGN | CKF_VERIFY | CKF_SIGN_RECOVER | CKF_VERIFY_RECOVER; - pInfo->ulMinKeySize = 1024; - pInfo->ulMaxKeySize = 2048; - break; -// case CKM_RSA_X_509: -// pInfo->flags = CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_SIGN | CKF_VERIFY | CKF_SIGN_RECOVER | CKF_VERIFY_RECOVER; -// pInfo->ulMinKeySize = 1024; -// pInfo->ulMaxKeySize = 2048; -// break; - case CKM_SHA1_RSA_PKCS: - case CKM_SHA256_RSA_PKCS: - pInfo->flags = CKF_HW | CKF_SIGN | CKF_VERIFY; - pInfo->ulMinKeySize = 1024; - pInfo->ulMaxKeySize = 2048; - break; - case CKM_MD5_RSA_PKCS: - pInfo->flags = CKF_HW | CKF_SIGN | CKF_VERIFY; - pInfo->ulMinKeySize = 1024; - pInfo->ulMaxKeySize = 2048; - break; - case CKM_MD5: - pInfo->flags = CKF_DIGEST; - pInfo->ulMinKeySize = 0; - pInfo->ulMaxKeySize = 0; - break; - case CKM_SHA_1: - pInfo->flags = CKF_DIGEST; - pInfo->ulMinKeySize = 0; - pInfo->ulMaxKeySize = 0; - case CKM_SHA256: - pInfo->flags = CKF_DIGEST; - pInfo->ulMinKeySize = 0; - pInfo->ulMaxKeySize = 0; - break; - default: - throw p11_error(CKR_MECHANISM_INVALID); - } - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_GetSessionInfo(CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkOutPtr(pInfo) - - logParam(hSession) - logParam(pInfo) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession = CSession::GetSessionFromID(hSession); - if (pSession == nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - pInfo->slotID = pSession->pSlot->hSlot; - - if (pSession->pSlot->User==CKU_NOBODY) { - if (pSession->flags & CKF_RW_SESSION) - pInfo->state=CKS_RW_PUBLIC_SESSION; - else - pInfo->state=CKS_RO_PUBLIC_SESSION; - } else if (pSession->pSlot->User==CKU_USER) { - if (pSession->flags & CKF_RW_SESSION) - pInfo->state=CKS_RW_USER_FUNCTIONS; - else - pInfo->state=CKS_RO_USER_FUNCTIONS; - } else - pInfo->state=CKS_RW_SO_FUNCTIONS; - - if (pSession->flags & CKF_RW_SESSION) - pInfo->flags = CKF_RW_SESSION; - else - pInfo->flags = 0; - - pInfo->flags = pInfo->flags | CKF_SERIAL_SESSION; - - pInfo->ulDeviceError = 0; - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG ulPinLen) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkInBuffer(pPin, ulPinLen) - - logParam(hSession) - logParam(userType) - logParamBufHide(pPin, ulPinLen) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession = CSession::GetSessionFromID(hSession); - if (pSession == nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - if (userType != CKU_SO && userType != CKU_USER) - throw p11_error(CKR_USER_TYPE_INVALID); - - pSession->Login(userType, pPin, ulPinLen); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_Logout(CK_SESSION_HANDLE hSession) { - init_p11_func - std::unique_lock lock(p11Mutex); - - logParam(hSession) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession = CSession::GetSessionFromID(hSession); - if (pSession == nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - if (pSession->pSlot->User == CKU_NOBODY) - throw p11_error(CKR_USER_NOT_LOGGED_IN); - - pSession->Logout(); - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_SetAttributeValue(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount) { - init_p11_func - std::unique_lock lock(p11Mutex); - - logParam(hSession) - logParam(hObject) - logParam(pTemplate) - logParam(ulCount) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession =CSession::GetSessionFromID(hSession); - - if (pSession == nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - pSession->SetAttributeValue(hObject, pTemplate, ulCount); - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; - -} - -CK_RV CK_ENTRY C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkInBuffer(pData, ulDataLen) -// checkOutArray(pSignature, pulSignatureLen) -// checkInBuffer(pData, ulDataLen) -// checkOutArray(pSignature, pulSignatureLen) - - logParam(hSession) - logParamBuf(pData, ulDataLen) - logParamBuf(pSignature, pulSignatureLen) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession =CSession::GetSessionFromID(hSession); - - if (pSession == nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - ByteArray Signature(pSignature,*pulSignatureLen); - ByteArray input(pData, ulDataLen); - pSession->Sign(input, Signature); - *pulSignatureLen = (CK_ULONG)Signature.size(); - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,CK_ULONG_PTR pulSignatureLen) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkOutArray(pSignature, pulSignatureLen) - - logParam(hSession) - logParamBuf(pSignature, pulSignatureLen) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession =CSession::GetSessionFromID(hSession); - - if (pSession == nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - if (!pSession->pSignMechanism->SignSupportMultipart()) - throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); - - ByteArray Signature(pSignature,*pulSignatureLen); - pSession->SignFinal(Signature); - *pulSignatureLen = (CK_ULONG)Signature.size(); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkInPtr(pMechanism) - - logParam(hSession) - logParam(pMechanism) - logParam(hKey) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession =CSession::GetSessionFromID(hSession); - - if (pSession == nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - - if (!CheckMechanismParam(pMechanism)) - throw p11_error(CKR_MECHANISM_PARAM_INVALID); - - pSession->SignInit(pMechanism, hKey); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} -CK_RV CK_ENTRY C_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkInBuffer(pPart, ulPartLen) - - logParam(hSession) - logParamBuf(pPart, ulPartLen) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession =CSession::GetSessionFromID(hSession); - - if (pSession == nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - if (!pSession->pSignMechanism->SignSupportMultipart()) - throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); - - ByteArray input(pPart, ulPartLen); - pSession->SignUpdate(input); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_SignRecoverInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkInPtr(pMechanism) - - logParam(hSession) - logParam(pMechanism) - logParam(hKey) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession =CSession::GetSessionFromID(hSession); - - if (pSession == nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - if (!CheckMechanismParam(pMechanism)) - throw p11_error(CKR_MECHANISM_PARAM_INVALID); - - pSession->SignRecoverInit(pMechanism, hKey); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkInBuffer(pData, ulDataLen) -// checkOutArray(pSignature, pulSignatureLen) - - logParam(hSession) - logParamBuf(pData, ulDataLen) - logParamBuf(pSignature, pulSignatureLen) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession =CSession::GetSessionFromID(hSession); - - if (pSession == nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - ByteArray Signature(pSignature,*pulSignatureLen); - ByteArray input(pData, ulDataLen); - pSession->SignRecover(input, Signature); - *pulSignatureLen = (CK_ULONG)Signature.size(); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_VerifyRecoverInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkInPtr(pMechanism) - - logParam(hSession) - logParam(pMechanism) - logParam(hKey) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession =CSession::GetSessionFromID(hSession); - - if (pSession == nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - - if (!CheckMechanismParam(pMechanism)) - throw p11_error(CKR_MECHANISM_PARAM_INVALID); - - pSession->VerifyRecoverInit(pMechanism, hKey); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_VerifyRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkOutArray(pData, pulDataLen) -// checkInBuffer(pSignature, ulSignatureLen) - - logParam(hSession) - logParamBuf(pSignature, ulSignatureLen) - logParamBuf(pData, pulDataLen) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession =CSession::GetSessionFromID(hSession); - - if (pSession == nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - ByteArray Data(pData,*pulDataLen); - ByteArray input(pSignature, ulSignatureLen); - pSession->VerifyRecover(input, Data); - *pulDataLen = (CK_ULONG)Data.size(); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_VerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkInPtr(pMechanism) - - logParam(hSession) - logParam(pMechanism) - logParam(hKey) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession =CSession::GetSessionFromID(hSession); - - if (pSession == nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - if (!CheckMechanismParam(pMechanism)) - throw p11_error(CKR_MECHANISM_PARAM_INVALID); - - pSession->VerifyInit(pMechanism, hKey); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkInBuffer(pData, ulDataLen) -// checkInBuffer(pSignature, ulSignatureLen) - - logParam(hSession) - logParamBuf(pData, ulDataLen) - logParamBuf(pSignature, ulSignatureLen) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession =CSession::GetSessionFromID(hSession); - - if (pSession == nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - ByteArray input(pData, ulDataLen); - ByteArray signature(pSignature, ulSignatureLen); - pSession->Verify(input, signature); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_VerifyUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkInBuffer(pData, ulDataLen) - - logParam(hSession) - logParamBuf(pData, ulDataLen) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession =CSession::GetSessionFromID(hSession); - - if (pSession == nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - if (!pSession->pVerifyMechanism->VerifySupportMultipart()) - throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); - - ByteArray input(pData, ulDataLen); - pSession->VerifyUpdate(input); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_VerifyFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkInBuffer(pSignature, ulSignatureLen) - - logParam(hSession) - logParamBuf(pSignature, ulSignatureLen) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession =CSession::GetSessionFromID(hSession); - - if (pSession == nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - if (!pSession->pVerifyMechanism->VerifySupportMultipart()) - throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); - - ByteArray input(pSignature, ulSignatureLen); - pSession->VerifyFinal(input); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen) { - init_p11_func - - return CKR_FUNCTION_NOT_SUPPORTED; - -// std::unique_lock lock(p11Mutex); -// -//// checkInBuffer(pData, ulDataLen) -//// checkOutArray(pEncryptedData, pulEncryptedDataLen) -// -// logParam(hSession) -// logParamBuf(pData, ulDataLen) -// logParamBuf(pEncryptedData, pulEncryptedDataLen) -// -// if (!bP11Initialized) -// throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); -// -// std::shared_ptr pSession = CSession::GetSessionFromID(hSession); -// -// if (pSession == nullptr) -// throw p11_error(CKR_SESSION_HANDLE_INVALID); -// -// ByteArray EncryptedData(pEncryptedData, *pulEncryptedDataLen); -// ByteArray input(pData, ulDataLen); -// pSession->Encrypt(input, EncryptedData); -// *pulEncryptedDataLen = (CK_ULONG)EncryptedData.size(); -// -// return CKR_OK; - exit_p11_func -// return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_EncryptFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pEncryptedData,CK_ULONG_PTR pulEncryptedDataLen) { - init_p11_func - - return CKR_FUNCTION_NOT_SUPPORTED; - -// std::unique_lock lock(p11Mutex); -// -//// checkOutArray(pEncryptedData, pulEncryptedDataLen) -// -// logParam(hSession) -// logParamBuf(pEncryptedData, pulEncryptedDataLen) -// -// if (!bP11Initialized) -// throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); -// -// std::shared_ptr pSession = CSession::GetSessionFromID(hSession); -// -// if (pSession == nullptr) -// throw p11_error(CKR_SESSION_HANDLE_INVALID); -// -// if (!pSession->pEncryptMechanism->EncryptSupportMultipart()) -// throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); -// -// ByteArray EncryptedData(pEncryptedData, *pulEncryptedDataLen); -// pSession->EncryptFinal(EncryptedData); -// *pulEncryptedDataLen = (CK_ULONG)EncryptedData.size(); -// -// return CKR_OK; - exit_p11_func -// return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { - init_p11_func - - return CKR_FUNCTION_NOT_SUPPORTED; - -// std::unique_lock lock(p11Mutex); -// -//// checkInPtr(pMechanism) -// -// logParam(hSession) -// logParam(pMechanism) -// logParam(hKey) -// -// if (!bP11Initialized) -// throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); -// -// std::shared_ptr pSession =CSession::GetSessionFromID(hSession); -// -// if (pSession == nullptr) -// throw p11_error(CKR_SESSION_HANDLE_INVALID); -// -// if (!CheckMechanismParam(pMechanism)) -// throw p11_error(CKR_MECHANISM_PARAM_INVALID); -// -// pSession->EncryptInit(pMechanism, hKey); -// -// return CKR_OK; - exit_p11_func -// return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_EncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen) { - init_p11_func - - return CKR_FUNCTION_NOT_SUPPORTED; - -// std::unique_lock lock(p11Mutex); -// -//// checkInBuffer(pPart, ulPartLen) -//// checkOutArray(pEncryptedPart, pulEncryptedPartLen) -// -// logParam(hSession) -// logParamBuf(pPart, ulPartLen) -// logParamBuf(pEncryptedPart, pulEncryptedPartLen) -// -// if (!bP11Initialized) -// throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); -// -// std::shared_ptr pSession =CSession::GetSessionFromID(hSession); -// -// if (pSession == nullptr) -// throw p11_error(CKR_SESSION_HANDLE_INVALID); -// -// if (!pSession->pEncryptMechanism->EncryptSupportMultipart()) -// throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); -// -// ByteArray EncryptedPart(pEncryptedPart, *pulEncryptedPartLen); -// ByteArray input(pPart, ulPartLen); -// pSession->EncryptUpdate(input, EncryptedPart); -// *pulEncryptedPartLen = (CK_ULONG)EncryptedPart.size(); -// -// return CKR_OK; - exit_p11_func -// return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_Decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) { - init_p11_func - return CKR_FUNCTION_NOT_SUPPORTED; - -// std::unique_lock lock(p11Mutex); -// -//// checkInBuffer(pEncryptedData, ulEncryptedDataLen) -//// checkOutArray(pData, pulDataLen) -// -// logParam(hSession) -// logParamBuf(pEncryptedData, ulEncryptedDataLen) -// logParamBuf(pData, pulDataLen) -// -// if (!bP11Initialized) -// throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); -// -// std::shared_ptr pSession =CSession::GetSessionFromID(hSession); -// -// if (pSession == nullptr) -// throw p11_error(CKR_SESSION_HANDLE_INVALID); -// -// ByteArray Data(pData, *pulDataLen); -// ByteArray input(pEncryptedData, ulEncryptedDataLen); -// pSession->Decrypt(input, Data); -// *pulDataLen = (CK_ULONG)Data.size(); -// -// return CKR_OK; - exit_p11_func -// return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_DecryptFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG_PTR pulDataLen) { - init_p11_func - - return CKR_FUNCTION_NOT_SUPPORTED; - -// std::unique_lock lock(p11Mutex); -// -//// checkOutArray(pData, pulDataLen) -// -// logParam(hSession) -// logParamBuf(pData, pulDataLen) -// -// if (!bP11Initialized) -// throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); -// -// std::shared_ptr pSession =CSession::GetSessionFromID(hSession); -// -// if (pSession == nullptr) -// throw p11_error(CKR_SESSION_HANDLE_INVALID); -// -// if (!pSession->pDecryptMechanism->DecryptSupportMultipart()) -// throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); -// -// ByteArray Data(pData, *pulDataLen); -// pSession->DecryptFinal(Data); -// *pulDataLen = (CK_ULONG)Data.size(); -// -// return CKR_OK; - exit_p11_func -// return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_DecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { - init_p11_func - - return CKR_FUNCTION_NOT_SUPPORTED; - -// std::unique_lock lock(p11Mutex); -// -//// checkInPtr(pMechanism) -// -// logParam(hSession) -// logParam(pMechanism) -// logParam(hKey) -// -// if (!bP11Initialized) -// throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); -// -// std::shared_ptr pSession =CSession::GetSessionFromID(hSession); -// -// if (pSession == nullptr) -// throw p11_error(CKR_SESSION_HANDLE_INVALID); -// -// -// if (!CheckMechanismParam(pMechanism)) -// throw p11_error(CKR_MECHANISM_PARAM_INVALID); -// -// pSession->DecryptInit(pMechanism, hKey); -// -// return CKR_OK; - exit_p11_func -// return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_DecryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) { - init_p11_func - - return CKR_FUNCTION_NOT_SUPPORTED; - -// std::unique_lock lock(p11Mutex); -// -//// checkInBuffer(pEncryptedPart, ulEncryptedPartLen) -//// checkOutArray(pPart, pulPartLen) -// -// logParam(hSession) -// logParamBuf(pEncryptedPart, ulEncryptedPartLen) -// logParamBuf(pPart, pulPartLen) -// -// if (!bP11Initialized) -// throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); -// -// std::shared_ptr pSession =CSession::GetSessionFromID(hSession); -// -// if (pSession == nullptr) -// throw p11_error(CKR_SESSION_HANDLE_INVALID); -// -// if (!pSession->pDecryptMechanism->DecryptSupportMultipart()) -// throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); -// -// ByteArray Part(pPart, *pulPartLen); -// ByteArray input(pEncryptedPart, ulEncryptedPartLen); -// pSession->DecryptUpdate(input, Part); -// *pulPartLen = (CK_ULONG)Part.size(); -// -// return CKR_OK; - exit_p11_func -// return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved) { - init_p11_func - -// checkOutPtr(pSlot) - - logParam(flags) - logParam(pSlot) - logParam(pReserved) - - if (pReserved != NULL) - throw p11_error(CKR_ARGUMENTS_BAD); - - if (flags != 0 && flags != CKF_DONT_BLOCK) - throw p11_error(CKR_ARGUMENTS_BAD); - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - if (flags & CKF_DONT_BLOCK) { - std::unique_lock lock(p11Mutex); - //CSyncroLocker lock(p11EventMutex); - SlotMap::iterator it=CSlot::g_mSlots.begin(); - while (it!=CSlot::g_mSlots.end()) { - if (it->second->lastEvent!=SE_NoEvent) { - *pSlot=it->second->hSlot; - it->second->lastEvent=SE_NoEvent; - return CKR_OK; - } - it++; - } - throw p11_error(CKR_NO_EVENT); - } - - while (1) { - p11slotEvent.wait(); - //CSyncroLocker lock(p11EventMutex); - if (!bP11Initialized) { - *pSlot=0; - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - } - SlotMap::iterator it=CSlot::g_mSlots.begin(); - while (it!=CSlot::g_mSlots.end()) { - if (it->second->lastEvent!=SE_NoEvent) { - *pSlot=it->second->hSlot; - it->second->lastEvent=SE_NoEvent; - return CKR_OK; - } - it++; - } - } - - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen) { - init_p11_func - - logParam(hSession) - logParamBuf(pSeed, ulSeedLen) - - throw p11_error(CKR_RANDOM_SEED_NOT_SUPPORTED); - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_GenerateRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR RandomData, CK_ULONG ulRandomLen) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkOutBuffer(RandomData, ulRandomLen) - - logParam(hSession) - logParamBuf(RandomData, ulRandomLen) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession =CSession::GetSessionFromID(hSession); - - if (pSession == nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - ByteArray input(RandomData, ulRandomLen); - pSession->GenerateRandom(input); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_InitPIN(CK_SESSION_HANDLE hSession,CK_CHAR_PTR pPin,CK_ULONG ulPinLen) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkInBuffer(pPin,ulPinLen); - - logParam(hSession) - logParamBufHide(pPin, ulPinLen) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession =CSession::GetSessionFromID(hSession); - - if (pSession == nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - ByteArray input(pPin, ulPinLen); - pSession->InitPIN(input); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_SetPIN(CK_SESSION_HANDLE hSession,CK_CHAR_PTR pOldPin,CK_ULONG ulOldLen,CK_CHAR_PTR pNewPin,CK_ULONG ulNewLen) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkInBuffer(pOldPin,ulOldLen); -// checkInBuffer(pNewPin,ulNewLen); - - logParam(hSession) - logParamBufHide(pOldPin, ulOldLen) - logParamBufHide(pNewPin, ulNewLen) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession =CSession::GetSessionFromID(hSession); - - if (pSession == nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - ByteArray inputOld(pOldPin, ulOldLen); - ByteArray inputNew(pNewPin, ulNewLen); - pSession->SetPIN(inputOld, inputNew); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_GetObjectSize(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,CK_ULONG_PTR pulSize) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkOutPtr(pulSize); - - logParam(hSession) - logParam(hObject) - logParam(pulSize) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession =CSession::GetSessionFromID(hSession); - - if (pSession == nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - *pulSize = pSession->GetObjectSize(hObject); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_GetOperationState(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pOperationState,CK_ULONG_PTR pulOperationStateLen) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkOutArray(pOperationState, pulOperationStateLen) - - logParam(hSession) - logParamBuf(pOperationState, pulOperationStateLen) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession =CSession::GetSessionFromID(hSession); - - if (pSession == nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - ByteArray OperationState(pOperationState,*pulOperationStateLen); - pSession->GetOperationState(OperationState); - *pulOperationStateLen = (CK_ULONG)OperationState.size(); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -CK_RV CK_ENTRY C_SetOperationState(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pOperationState,CK_ULONG ulOperationStateLen,CK_OBJECT_HANDLE hEncryptionKey,CK_OBJECT_HANDLE hAuthenticationKey) { - init_p11_func - std::unique_lock lock(p11Mutex); - -// checkInBuffer(pOperationState, ulOperationStateLen) - - logParam(hSession) - logParamBuf(pOperationState, ulOperationStateLen) - logParam(hEncryptionKey) - logParam(hAuthenticationKey) - - if (!bP11Initialized) - throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); - - std::shared_ptr pSession =CSession::GetSessionFromID(hSession); - - if (pSession == nullptr) - throw p11_error(CKR_SESSION_HANDLE_INVALID); - - if (hEncryptionKey != CK_INVALID_HANDLE) - throw p11_error(CKR_KEY_NOT_NEEDED); - if (hAuthenticationKey != CK_INVALID_HANDLE) - throw p11_error(CKR_KEY_NOT_NEEDED); - - ByteArray input(pOperationState, ulOperationStateLen); - pSession->SetOperationState(input); - - return CKR_OK; - exit_p11_func - return CKR_GENERAL_ERROR; -} - -#define unsupported \ -{ \ - init_p11_func \ - Log.write("%s","Funzione non supportata!!"); \ - throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); \ - exit_p11_func \ - return CKR_FUNCTION_NOT_SUPPORTED; \ -} - -CK_RV CK_ENTRY C_InitToken(CK_SLOT_ID slotID,CK_CHAR_PTR pPin,CK_ULONG ulPinLen,CK_UTF8CHAR_PTR pLabel) unsupported -CK_RV CK_ENTRY C_CopyObject(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phNewObject) unsupported -CK_RV CK_ENTRY C_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey) unsupported -CK_RV CK_ENTRY C_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen) unsupported -CK_RV CK_ENTRY C_DecryptDigestUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) unsupported -CK_RV CK_ENTRY C_SignEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen) unsupported -CK_RV CK_ENTRY C_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) unsupported -CK_RV CK_ENTRY C_WrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen) unsupported -CK_RV CK_ENTRY C_UnwrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey) unsupported -CK_RV CK_ENTRY C_DeriveKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey) unsupported -CK_RV CK_ENTRY C_GetFunctionStatus(CK_SESSION_HANDLE hSession) unsupported -CK_RV CK_ENTRY C_CancelFunction(CK_SESSION_HANDLE hSession) unsupported - - -char *getAttributeName(unsigned long dwId) { - switch (dwId) { - case 0x00000000: - return("CKA_CLASS"); - case 0x00000001: - return("CKA_TOKEN"); - case 0x00000002: - return("CKA_PRIVATE"); - case 0x00000003: - return("CKA_LABEL"); - case 0x00000010: - return("CKA_APPLICATION"); - case 0x00000011: - return("CKA_VALUE"); - case 0x00000012: - return("CKA_OBJECT_ID"); - case 0x00000080: - return("CKA_CERTIFICATE_TYPE"); - case 0x00000081: - return("CKA_ISSUER"); - case 0x00000082: - return("CKA_SERIAL_NUMBER"); - case 0x00000083: - return("CKA_AC_ISSUER"); - case 0x00000084: - return("CKA_OWNER"); - case 0x00000085: - return("CKA_ATTR_TYPES"); - case 0x00000086: - return("CKA_TRUSTED"); - case 0x00000100: - return("CKA_KEY_TYPE"); - case 0x00000101: - return("CKA_SUBJECT"); - case 0x00000102: - return("CKA_ID"); - case 0x00000103: - return("CKA_SENSITIVE"); - case 0x00000104: - return("CKA_ENCRYPT"); - case 0x00000105: - return("CKA_DECRYPT"); - case 0x00000106: - return("CKA_WRAP"); - case 0x00000107: - return("CKA_UNWRAP"); - case 0x00000108: - return("CKA_SIGN"); - case 0x00000109: - return("CKA_SIGN_RECOVER"); - case 0x0000010A: - return("CKA_VERIFY"); - case 0x0000010B: - return("CKA_VERIFY_RECOVER"); - case 0x0000010C: - return("CKA_DERIVE"); - case 0x00000110: - return("CKA_START_DATE"); - case 0x00000111: - return("CKA_END_DATE"); - case 0x00000120: - return("CKA_MODULUS"); - case 0x00000121: - return("CKA_MODULUS_BITS"); - case 0x00000122: - return("CKA_PUBLIC_EXPONENT"); - case 0x00000123: - return("CKA_PRIVATE_EXPONENT"); - case 0x00000124: - return("CKA_PRIME_1"); - case 0x00000125: - return("CKA_PRIME_2"); - case 0x00000126: - return("CKA_EXPONENT_1"); - case 0x00000127: - return("CKA_EXPONENT_2"); - case 0x00000128: - return("CKA_COEFFICIENT"); - case 0x00000130: - return("CKA_PRIME"); - case 0x00000131: - return("CKA_SUBPRIME"); - case 0x00000132: - return("CKA_BASE"); - case 0x00000133: - return("CKA_PRIME_BITS"); - case 0x00000134: - return("CKA_SUB_PRIME_BITS"); - case 0x00000160: - return("CKA_VALUE_BITS"); - case 0x00000161: - return("CKA_VALUE_LEN"); - case 0x00000162: - return("CKA_EXTRACTABLE"); - case 0x00000163: - return("CKA_LOCAL"); - case 0x00000164: - return("CKA_NEVER_EXTRACTABLE"); - case 0x00000165: - return("CKA_ALWAYS_SENSITIVE"); - case 0x00000166: - return("CKA_KEY_GEN_MECHANISM"); - case 0x00000170: - return("CKA_MODIFIABLE"); - case 0x00000180: - return("CKA_EC_PARAMS"); - case 0x00000181: - return("CKA_EC_POINT"); - case 0x00000200: - return("CKA_SECONDARY_AUTH"); - case 0x00000201: - return("CKA_AUTH_PIN_FLAGS"); - case 0x00000300: - return("CKA_HW_FEATURE_TYPE"); - case 0x00000301: - return("CKA_RESET_ON_INIT"); - case 0x00000302: - return("CKA_HAS_RESET"); - case 0x80000000: - return("CKA_VENDOR_DEFINED"); - case 0x80000001: - return("CKA_SM"); - case 0x80000002: - return("CKA_SM_PUB"); - } - return("UNKNOWN"); -} - - - +// P11Emissione.cpp : Defines the entry point for the DLL application. +// +#include +#include +#include +#include "wintypes.h" +#include "PKCS11Functions.h" +#include "InitP11.h" +#ifdef WIN32 +#include +#else +#include +#endif +#include "session.h" +#include "CardTemplate.h" +#ifdef WIN32 +#include +#else +#include +#endif +#include "../Util/ModuleInfo.h" +#include "../Util/util.h" +#include "../Util/SyncroEvent.h" +#include + +#include +#include "../Util/UUCByteArray.h" +#include "../LOGGER/Logger.h" + +using namespace CieIDLogger; + +extern CLog Log; + +// flag: P11 inizializzato +bool bP11Initialized=false; +bool bP11Terminate=false; + +using namespace p11; + +std::mutex p11Mutex; +auto_reset_event p11slotEvent/*("CardOS_P11_Event")*/; + +// meccanismi supportati + + +CK_MECHANISM_TYPE P11mechanisms[]= { + //CKM_RSA_PKCS_KEY_PAIR_GEN, + CKM_RSA_PKCS, + CKM_MD5, + CKM_SHA_1, + CKM_SHA256, + CKM_SHA1_RSA_PKCS, + CKM_SHA256_RSA_PKCS, + CKM_MD5_RSA_PKCS +}; + + +char *getAttributeName(unsigned long dwId); +//extern CModuleInfo moduleInfo; // informazioni sulla dll (o so) +bool bModuleInit=false; + +#ifdef WIN32 +// funzione DllMain +// inizilizzo moduleInfo +BOOL APIENTRY DllMainP11( HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) { + if (ul_reason_for_call==DLL_PROCESS_ATTACH && !bModuleInit) { + bModuleInit=true; + moduleInfo.init(hModule); + std::string mainMutexName; + //mainMutexName="CIE_P11_Mutex_"+moduleInfo.szModuleName; + //p11Mutex.Create(mainMutexName.c_str()); + //xmlInit(); + std::string configPath; + configPath = moduleInfo.szModulePath + moduleInfo.szModuleName + ".ini"; + initLog(configPath.c_str(), __DATE__ " " __TIME__); + + p11::InitP11(configPath.c_str()); + + } + + if (ul_reason_for_call==DLL_PROCESS_DETACH && bModuleInit) { + + if (bP11Initialized) { + LOG_INFO("[PKCS11] DllMainP11 - Forzatura C_Finalize"); + C_Finalize(NULL); + bP11Initialized = false; + } + //xmlCleanup(); + bModuleInit=false; + bP11Terminate=true; + + CSlot::DeleteSlotList(); + CCardTemplate::DeleteTemplateList(); + p11slotEvent.set(); + + } + + return TRUE; +} + +#else + +/* ---- GENERATE CK_FUNCTION_LIST */ + +#define CK_PKCS11_FUNCTION_INFO(name) \ +name, +// +//CK_FUNCTION_LIST pkcs11_function_list = { +// { LIBRARY_VERSION_MAJOR, LIBRARY_VERSION_MINOR }, +//#include "pkcs11f.h" +//}; +#undef CK_PKCS11_FUNCTION_INFO + + +__attribute__((constructor)) void DllMainAttach() { + // code + const char *homedir; + if ((homedir = getenv("HOME")) == NULL) { + homedir = getpwuid(getuid())->pw_dir; + } + bModuleInit=true; + std::string configPath = std::string(homedir) + "/.CIEPKI/ciepki.ini"; + initLog("CIEPKC11", configPath.c_str(), __DATE__ " " __TIME__); + p11::InitP11(configPath.c_str()); +} + +__attribute__((destructor)) void DllMainDetach() { + LOG_INFO("[PKCS11] DllMainDetach"); + + if (bP11Initialized) { + LOG_INFO("[PKCS11] DllMainDetach - Forzatura C_Finalize"); + C_Finalize(NULL); + bP11Initialized = false; + + CSlot::DeleteSlotList(); + CCardTemplate::DeleteTemplateList(); + try { + p11slotEvent.set(); + } catch(...) { + LOG_ERROR("[PKCS11] DllMainDetach - event set error"); + } + } + + //xmlCleanup(); + bModuleInit=false; + bP11Terminate=true; +} + +#endif + +void WriteAttributes(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { + LOG_INFO("[PKCS11] WriteAttributes - Attributes: %x", ulCount); + + for(unsigned int i = 0; i < ulCount; i++) { + if(pTemplate[i].pValue) { + switch(pTemplate[i].type) { + case CKA_CLASS: + LOG_DEBUG("[PKCS11] WriteAttributes - %d) type=%x (%s), value=%x, len=%x", i + 1, pTemplate[i].type, getAttributeName(pTemplate[i].type), *(CK_OBJECT_CLASS_PTR)(pTemplate[i].pValue), pTemplate[i].ulValueLen); + break; + + case CKA_TOKEN: + case CKA_PRIVATE: + case CKA_MODIFIABLE: + LOG_DEBUG("[PKCS11] WriteAttributes - %d) type=%x (%s), value=%x, len=%x", i + 1, pTemplate[i].type, getAttributeName(pTemplate[i].type), *(CK_BBOOL*)(pTemplate[i].pValue), pTemplate[i].ulValueLen); + break; + + case CKA_LABEL: + case CKA_OBJECT_ID: + LOG_DEBUG("[PKCS11] WriteAttributes - %d) type=%x (%s), value=%s, len=%x", i + 1, pTemplate[i].type, getAttributeName(pTemplate[i].type), (char*)(pTemplate[i].pValue), pTemplate[i].ulValueLen); + break; + + case CKA_VALUE: + LOG_DEBUG("[PKCS11] WriteAttributes - %d) type=%x (%s), value=%s, len=%x", i + 1, pTemplate[i].type, getAttributeName(pTemplate[i].type), UUCByteArray((BYTE*)pTemplate[i].pValue, pTemplate[i].ulValueLen).toHexString(), pTemplate[i].ulValueLen); + break; + + default: + LOG_DEBUG("[PKCS11] WriteAttributes - %d) type=%x (%s), value=%p, len=%x", i + 1, pTemplate[i].type, getAttributeName(pTemplate[i].type), pTemplate[i].pValue, pTemplate[i].ulValueLen); + break; + } + } else { + switch(pTemplate[i].type) { + case CKA_CLASS: + LOG_DEBUG("[PKCS11] WriteAttributes - %d) type=%x (%s), value=NULL, len=%x", i + 1, pTemplate[i].type, getAttributeName(pTemplate[i].type), pTemplate[i].ulValueLen); + break; + + case CKA_TOKEN: + case CKA_PRIVATE: + case CKA_MODIFIABLE: + LOG_DEBUG("[PKCS11] WriteAttributes - %d) type=%x (%s), value=NULL, len=%x", i + 1, pTemplate[i].type, getAttributeName(pTemplate[i].type), pTemplate[i].ulValueLen); + break; + + case CKA_LABEL: + case CKA_OBJECT_ID: + LOG_DEBUG("[PKCS11] WriteAttributes - %d) type=%x (%s), value=NULL, len=%x", i + 1, pTemplate[i].type, getAttributeName(pTemplate[i].type), pTemplate[i].ulValueLen); + break; + + default: + LOG_DEBUG("[PKCS11] WriteAttributes - %d) type=%x (%s), value=NULL, len=%x", i + 1, pTemplate[i].type, getAttributeName(pTemplate[i].type), pTemplate[i].ulValueLen); + break; + } + } + } +} + +void WriteMechanism(CK_MECHANISM_PTR pMechanism) { + LOG_DEBUG("[PKCS11] WriteMechanism - Mechanism : %x", pMechanism->mechanism); + LOG_DEBUG("[PKCS11] WriteMechanism - Parameter: %x", pMechanism->pParameter); + LOG_DEBUG("[PKCS11] WriteMechanism - Parameter len: %x", pMechanism->ulParameterLen); +} + +// funzione CheckMechanismParam +bool CheckMechanismParam(CK_MECHANISM *pParam) { + init_func + // tutti i mechanism non hanno parametri + if (pParam->pParameter==NULL && pParam->ulParameterLen==0) { + return true; + } + return false; +} + +CK_RV CK_ENTRY C_UpdateSlotList() { + init_p11_func + std::unique_lock lock(p11Mutex); + + CSlot::InitSlotList(); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_AbilitaCIE(const char* szPAN, const char* szPIN) { //, PROGRESS_CALLBACK progressCallBack) + return 0; +} + +CK_RV CK_ENTRY C_GetSlotList(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkOutArray(pSlotList, pulCount) + + logParam(tokenPresent) + logParam(pSlotList) + logParam(pulCount) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + bool bOver=false; + std::vector slotsRet; + unsigned int iCnt; + if (tokenPresent) { + // solo i lettori con la carta inserita + iCnt=0; + + if (CSlot::g_mSlots.size()==0) { + *pulCount=0; + return CKR_OK; + + } + SlotMap::const_iterator it=CSlot::g_mSlots.end(); + do { + it--; + std::shared_ptr pSlot=it->second; + + if (pSlot->IsTokenPresent()) { + if (pSlotList) { + if (iCnt<*pulCount) + pSlotList[iCnt]=pSlot->hSlot; + else + bOver=true; + } + iCnt++; + } + } while (it!=CSlot::g_mSlots.begin()); + } else { + // restituisco tutti i lettori + if (!pSlotList) { + iCnt=(CK_ULONG)CSlot::g_mSlots.size(); + } else { + iCnt=0; + SlotMap::const_iterator it=CSlot::g_mSlots.end(); + while (it!=CSlot::g_mSlots.begin()) { + it--; + if (iCnt<*pulCount) + pSlotList[iCnt]=it->first; + else + bOver=true; + iCnt++; + } + } + } + *pulCount=iCnt; + if (bOver) + throw p11_error(CKR_BUFFER_TOO_SMALL); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_Initialize(CK_VOID_PTR pReserved) { + init_p11_func + std::unique_lock lock(p11Mutex); + + logParam(pReserved) + +// CK_C_INITIALIZE_ARGS_PTR ptr=(CK_C_INITIALIZE_ARGS_PTR)pReserved; + + if (bP11Initialized) + return CKR_OK; + // throw p11_error(CKR_CRYPTOKI_ALREADY_INITIALIZED) + + // verifico che i flag siano supportati + CK_C_INITIALIZE_ARGS_PTR iargs = NULL_PTR; + if (pReserved) { + iargs = (CK_C_INITIALIZE_ARGS_PTR)pReserved; + if (iargs->pReserved != NULL) + throw p11_error(CKR_ARGUMENTS_BAD); + + if (iargs->flags & CKF_OS_LOCKING_OK) { + if ((iargs->CreateMutex) || (iargs->DestroyMutex) || (iargs->LockMutex) || (iargs->UnlockMutex)) + throw p11_error(CKR_CANT_LOCK); + } else if (iargs->flags == 0) { + if ((iargs->CreateMutex) || (iargs->DestroyMutex) || (iargs->LockMutex) || (iargs->UnlockMutex)) + throw p11_error(CKR_CANT_LOCK); + } else if (iargs->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) + throw p11_error(CKR_NEED_TO_CREATE_THREADS); + else + throw p11_error(CKR_ARGUMENTS_BAD); + } + + + if (CCardTemplate::g_mCardTemplates.size()==0) + CCardTemplate::InitTemplateList(); + + bP11Initialized = true; + + CSlot::InitSlotList(); + + LOG_INFO("[PKCS11] C_Initialize success"); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_Finalize(CK_VOID_PTR pReserved) { + init_p11_func + std::unique_lock lock(p11Mutex); + + logParam(pReserved) + + if (pReserved != NULL) + throw p11_error(CKR_ARGUMENTS_BAD); + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + bP11Initialized = false; + + // TODO verificare thread "vuoto" + if (CSlot::Thread.joinable()) { + CCardContext *tc = CSlot::ThreadContext; + if (tc != nullptr) { + SCARDCONTEXT hC = tc->hContext; + if (hC != NULL) + SCardCancel(hC); + } + p11Mutex.unlock(); + CSlot::Thread.join(); + p11Mutex.lock(); + } + + + for(SlotMap::const_iterator it=CSlot::g_mSlots.begin(); it!=CSlot::g_mSlots.end(); it++) { + it->second->CloseAllSessions(); + } + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, CK_NOTIFY notify, CK_SESSION_HANDLE_PTR phSession) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkOutPtr(phSession) + + logParam(slotID) + logParam(flags) + logParam(pApplication) + logParam(notify) + logParam(phSession) + + + if (!bP11Initialized) { + LOG_ERROR("[PKCS11] C_OpenSession - CKR_CRYPTOKI_NOT_INITIALIZED"); + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + } + + if (!(flags & CKF_SERIAL_SESSION)) { + LOG_ERROR("[PKCS11] C_OpenSession - CKF_SERIAL_SESSION"); + throw p11_error(CKR_SESSION_PARALLEL_NOT_SUPPORTED); + } + + std::shared_ptr pSlot = CSlot::GetSlotFromID(slotID); + if (pSlot == nullptr) { + LOG_ERROR("[PKCS11] C_OpenSession - CKR_SLOT_ID_INVALID"); + throw p11_error(CKR_SLOT_ID_INVALID); + } + + auto pSession = std::unique_ptr(new CSession()); + pSession->pSlot=pSlot; + pSession->flags=flags; + pSession->notify=notify; + pSession->pApplication=pApplication; + + if ((flags & CKF_RW_SESSION)==0) { + // se una sessione RO devo + // verificare che non ci siano sessioni SO RW + if (pSession->ExistsSO_RW()) { + LOG_ERROR("[PKCS11] C_OpenSession - CKR_SESSION_READ_WRITE_SO_EXISTS"); + throw p11_error(CKR_SESSION_READ_WRITE_SO_EXISTS); + } + + } + + pSlot->Init(); + + pSession->slotID=slotID; + +// aggiungo la sessione all'elenco globale + *phSession = CSession::AddSession(std::move(pSession)); + + LOG_INFO("[PKCS11] C_OpenSession - Sessione: %i",*phSession); + LOG_INFO("[PKCS11] C_OpenSession - Lettore: %s",pSlot->szName.c_str()); + LOG_INFO("[PKCS11] C_OpenSession - CardManager: %s",pSlot->pTemplate->szName.c_str()); + std::string szModel; + pSlot->pTemplate->FunctionList.templateGetModel(*pSlot,szModel); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkOutPtr(pInfo) + + logParam(slotID) + logParam(pInfo) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSlot = CSlot::GetSlotFromID(slotID); + + if (pSlot == nullptr) + throw p11_error(CKR_SLOT_ID_INVALID); + + if (pInfo == nullptr) + throw p11_error(CKR_ARGUMENTS_BAD); + + if (!pSlot->IsTokenPresent()) + throw p11_error(CKR_TOKEN_NOT_PRESENT); + + pSlot->GetTokenInfo(pInfo); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_CloseSession(CK_SESSION_HANDLE hSession) { + init_p11_func + std::unique_lock lock(p11Mutex); + + logParam(hSession) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession = CSession::GetSessionFromID(hSession); + + if (pSession==nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + CSession::DeleteSession(hSession); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_CloseAllSessions(CK_SLOT_ID slotID) { + init_p11_func + std::unique_lock lock(p11Mutex); + + logParam(slotID) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSlot = CSlot::GetSlotFromID(slotID); + + if (pSlot==nullptr) + throw p11_error(CKR_SLOT_ID_INVALID); + + pSlot->CloseAllSessions(); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + + +CK_RV CK_ENTRY C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkOutPtr(pInfo) + + logParam(slotID) + logParam(pInfo) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSlot = CSlot::GetSlotFromID(slotID); + if (pSlot==NULL) + throw p11_error(CKR_SLOT_ID_INVALID); + + if (pInfo == NULL) + throw p11_error(CKR_ARGUMENTS_BAD); + + pSlot->GetInfo(pInfo); + + LOG_DEBUG("[PKCS11] C_GetSlotInfo - slotDescription: %s", pInfo->slotDescription); + //LOG_DEBUG("[PKCS11] C_GetSlotInfo - manufacturerID: %s", pInfo->manufacturerID); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_GetInfo(CK_INFO_PTR pInfo /* location that receives information */) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkOutPtr(pInfo) + + logParam(pInfo) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + pInfo->cryptokiVersion.major = 2; /* Cryptoki interface ver */ + pInfo->cryptokiVersion.minor = 10; //12345678901234567890123456789012 + CryptoPP::memcpy_s((char*)pInfo->manufacturerID,32,"IPZS\0 ", 32); + + pInfo->flags = 0; /* must be zero */ + + /* libraryDescription and libraryVersion are new for v2.0 */ + CryptoPP::memcpy_s((char*)pInfo->libraryDescription,32,"CIE PKCS11\0 ", 32); + + pInfo->libraryVersion.major = 1; /* version of library */ + pInfo->libraryVersion.minor = 0; /* version of library */ + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkOutPtr(ppFunctionList) + + logParam(ppFunctionList) + + if (ppFunctionList == NULL) + throw p11_error(CKR_ARGUMENTS_BAD); + + static CK_FUNCTION_LIST functionList = {{ 2, 20}, + C_Initialize, + C_Finalize, + C_GetInfo, + C_GetFunctionList, + C_GetSlotList, + C_GetSlotInfo, + C_GetTokenInfo, + C_GetMechanismList, + C_GetMechanismInfo, + C_InitToken, + C_InitPIN, + C_SetPIN, + C_OpenSession, + C_CloseSession, + C_CloseAllSessions, + C_GetSessionInfo, + C_GetOperationState, + C_SetOperationState, + C_Login, + C_Logout, + C_CreateObject, + C_CopyObject, + C_DestroyObject, + C_GetObjectSize, + C_GetAttributeValue, + C_SetAttributeValue, + C_FindObjectsInit, + C_FindObjects, + C_FindObjectsFinal, + C_EncryptInit, + C_Encrypt, + C_EncryptUpdate, + C_EncryptFinal, + C_DecryptInit, + C_Decrypt, + C_DecryptUpdate, + C_DecryptFinal, + C_DigestInit, + C_Digest, + C_DigestUpdate, C_DigestKey, C_DigestFinal, C_SignInit, C_Sign, + C_SignUpdate, C_SignFinal, C_SignRecoverInit, C_SignRecover, + C_VerifyInit, C_Verify, C_VerifyUpdate, C_VerifyFinal, + C_VerifyRecoverInit, C_VerifyRecover, C_DigestEncryptUpdate, + C_DecryptDigestUpdate, C_SignEncryptUpdate, C_DecryptVerifyUpdate, + C_GenerateKey, C_GenerateKeyPair, C_WrapKey, C_UnwrapKey, + C_DeriveKey, C_SeedRandom, C_GenerateRandom, C_GetFunctionStatus, + C_CancelFunction, C_WaitForSlotEvent + }; + + *ppFunctionList = &functionList; + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_CreateObject(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject) { + init_p11_func + std::unique_lock lock(p11Mutex); + + +// checkOutPtr(phObject) + + logParam(hSession) + logParam(pTemplate) + logParam(ulCount) + logParam(phObject) + + WriteAttributes(pTemplate, ulCount); + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession = CSession::GetSessionFromID(hSession); + + if (pSession==nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + *phObject = pSession->CreateObject(pTemplate, ulCount); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_GenerateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkInPtr(pMechanism) +// checkOutPtr(phKey) + + logParam(hSession) + logParam(pMechanism) + logParam(pTemplate) + logParam(ulCount) + logParam(phKey) + + WriteAttributes(pTemplate, ulCount); + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession = CSession::GetSessionFromID(hSession); + + if (pSession == nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + *phKey = pSession->GenerateKey(pMechanism, pTemplate, ulCount); + return CKR_OK; + + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_GenerateKeyPair(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkInPtr(pMechanism) +// checkOutPtr(phPublicKey) +// checkOutPtr(phPrivateKey) + + logParam(hSession) + logParam(pMechanism) + logParam(pPublicKeyTemplate) + logParam(pPrivateKeyTemplate) + logParam(ulPublicKeyAttributeCount) + logParam(ulPrivateKeyAttributeCount) + logParam(phPublicKey) + logParam(phPrivateKey) + + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession = CSession::GetSessionFromID(hSession); + + if (pSession==nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + pSession->GenerateKeyPair(pMechanism, pPublicKeyTemplate, ulPublicKeyAttributeCount, pPrivateKeyTemplate, ulPrivateKeyAttributeCount, phPublicKey, phPrivateKey); + return CKR_OK; + + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_DestroyObject(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject) { + init_p11_func + std::unique_lock lock(p11Mutex); + + logParam(hSession) + logParam(hObject) + + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession = CSession::GetSessionFromID(hSession); + + if (pSession == nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + pSession->DestroyObject(hObject); + return CKR_OK; + + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_DigestInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkInPtr(pMechanism) + + logParam(hSession) + logParam(pMechanism) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession = CSession::GetSessionFromID(hSession); + if (pSession==nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + if (!CheckMechanismParam(pMechanism)) + throw p11_error(CKR_MECHANISM_PARAM_INVALID); + + pSession->DigestInit(pMechanism); + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_Digest(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkInBuffer(pData, ulDataLen) +// checkOutArray(pDigest, pulDigestLen) + + logParam(hSession) + logParamBuf(pData, ulDataLen) + logParamBuf(pDigest, pulDigestLen) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession = CSession::GetSessionFromID(hSession); + + if (pSession == nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + ByteArray Digest(pDigest, *pulDigestLen); + ByteArray input(pData, ulDataLen); + pSession->Digest(input, Digest); + *pulDigestLen = (CK_ULONG)Digest.size(); + +// ByteDynArray Digest = ByteArray(pDigest, *pulDigestLen); +// ByteArray input(pData, ulDataLen); +// pSession->Digest(input, Digest); +// *pulDigestLen = (CK_ULONG)Digest.size(); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_DigestFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkOutArray(pDigest, pulDigestLen) + + logParam(hSession) + logParamBuf(pDigest, pulDigestLen) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession = CSession::GetSessionFromID(hSession); + + if (pSession==nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + ByteDynArray Digest = ByteArray(pDigest, *pulDigestLen); + pSession->DigestFinal(Digest); + *pulDigestLen = (CK_ULONG)Digest.size(); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_DigestUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkInBuffer(pPart, ulPartLen) + + logParam(hSession) + logParamBuf(pPart, ulPartLen) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession = CSession::GetSessionFromID(hSession); + if (pSession==nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + ByteArray input(pPart, ulPartLen); + pSession->DigestUpdate(input); + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_FindObjects(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE_PTR phObject,CK_ULONG ulMaxObjectCount,CK_ULONG_PTR pulObjectCount) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkOutBuffer(phObject, sizeof(CK_OBJECT_HANDLE)*ulMaxObjectCount) + + logParam(hSession) + logParam(phObject) + logParam(ulMaxObjectCount) + logParam(pulObjectCount) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession = CSession::GetSessionFromID(hSession); + if (pSession == nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + if (phObject == NULL && ulMaxObjectCount > 0) + throw p11_error(CKR_ARGUMENTS_BAD); + + pSession->FindObjects(phObject, ulMaxObjectCount, pulObjectCount); + + LOG_DEBUG("[PKCS11] C_FindObjects - Objects found: %d", *pulObjectCount); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_FindObjectsFinal(CK_SESSION_HANDLE hSession) { + init_p11_func + std::unique_lock lock(p11Mutex); + + logParam(hSession) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession = CSession::GetSessionFromID(hSession); + if (pSession==nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + pSession->FindObjectsFinal(); + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} +CK_RV CK_ENTRY C_FindObjectsInit(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkInArray(pTemplate,ulCount) + + logParam(hSession) + logParam(pTemplate) + logParam(ulCount) + + WriteAttributes(pTemplate, ulCount); + +// if (Log.LogParam) { +// for (DWORD i=0;i pSession = CSession::GetSessionFromID(hSession); + if (pSession == nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + if (pTemplate == NULL && ulCount > 0) + throw p11_error(CKR_ARGUMENTS_BAD); + + pSession->FindObjectsInit(pTemplate, ulCount); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_GetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkInArray(pTemplate, ulCount) + + logParam(hSession) + logParam(hObject) + logParam(pTemplate) + logParam(ulCount) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession = CSession::GetSessionFromID(hSession); + if (pSession==nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + LOG_DEBUG("[PKCS11] C_GetAttributeValue - In template"); + WriteAttributes(pTemplate, ulCount); + + CK_RV rv = pSession->GetAttributeValue(hObject, pTemplate, ulCount); + +// if (Log.LogParam) { +// for (DWORD i=0;i lock(p11Mutex); + +// checkOutArray(pMechanismList,pulCount) + + logParam(slotID) + logParam(pMechanismList) + logParam(pulCount) + + DWORD dwNumMechansms=sizeof(P11mechanisms)/sizeof(CK_MECHANISM_TYPE); + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSlot = CSlot::GetSlotFromID(slotID); + if (pSlot == nullptr) + throw p11_error(CKR_SLOT_ID_INVALID); + + if (pMechanismList == nullptr) { + *pulCount = dwNumMechansms; + return CKR_OK; + } + + if (*pulCount >= dwNumMechansms) { + CryptoPP::memcpy_s(pMechanismList, dwNumMechansms * sizeof(CK_MECHANISM_TYPE), P11mechanisms, dwNumMechansms * sizeof(CK_MECHANISM_TYPE)); + return CKR_OK; + } else + throw p11_error(CKR_BUFFER_TOO_SMALL); + + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo) { + init_p11_func + std::unique_lock lock(p11Mutex); + + logParam(slotID) + logParam(type) + logParam(pInfo) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSlot=CSlot::GetSlotFromID(slotID); + + if (pSlot == nullptr) + throw p11_error(CKR_SLOT_ID_INVALID); + + switch (type) { + case CKM_RSA_PKCS: + pInfo->flags = CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_SIGN | CKF_VERIFY | CKF_SIGN_RECOVER | CKF_VERIFY_RECOVER; + pInfo->ulMinKeySize = 1024; + pInfo->ulMaxKeySize = 2048; + break; +// case CKM_RSA_X_509: +// pInfo->flags = CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_SIGN | CKF_VERIFY | CKF_SIGN_RECOVER | CKF_VERIFY_RECOVER; +// pInfo->ulMinKeySize = 1024; +// pInfo->ulMaxKeySize = 2048; +// break; + case CKM_SHA1_RSA_PKCS: + case CKM_SHA256_RSA_PKCS: + pInfo->flags = CKF_HW | CKF_SIGN | CKF_VERIFY; + pInfo->ulMinKeySize = 1024; + pInfo->ulMaxKeySize = 2048; + break; + case CKM_MD5_RSA_PKCS: + pInfo->flags = CKF_HW | CKF_SIGN | CKF_VERIFY; + pInfo->ulMinKeySize = 1024; + pInfo->ulMaxKeySize = 2048; + break; + case CKM_MD5: + pInfo->flags = CKF_DIGEST; + pInfo->ulMinKeySize = 0; + pInfo->ulMaxKeySize = 0; + break; + case CKM_SHA_1: + pInfo->flags = CKF_DIGEST; + pInfo->ulMinKeySize = 0; + pInfo->ulMaxKeySize = 0; + case CKM_SHA256: + pInfo->flags = CKF_DIGEST; + pInfo->ulMinKeySize = 0; + pInfo->ulMaxKeySize = 0; + break; + default: + throw p11_error(CKR_MECHANISM_INVALID); + } + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_GetSessionInfo(CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkOutPtr(pInfo) + + logParam(hSession) + logParam(pInfo) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession = CSession::GetSessionFromID(hSession); + if (pSession == nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + pInfo->slotID = pSession->pSlot->hSlot; + + if (pSession->pSlot->User==CKU_NOBODY) { + if (pSession->flags & CKF_RW_SESSION) + pInfo->state=CKS_RW_PUBLIC_SESSION; + else + pInfo->state=CKS_RO_PUBLIC_SESSION; + } else if (pSession->pSlot->User==CKU_USER) { + if (pSession->flags & CKF_RW_SESSION) + pInfo->state=CKS_RW_USER_FUNCTIONS; + else + pInfo->state=CKS_RO_USER_FUNCTIONS; + } else + pInfo->state=CKS_RW_SO_FUNCTIONS; + + if (pSession->flags & CKF_RW_SESSION) + pInfo->flags = CKF_RW_SESSION; + else + pInfo->flags = 0; + + pInfo->flags = pInfo->flags | CKF_SERIAL_SESSION; + + pInfo->ulDeviceError = 0; + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG ulPinLen) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkInBuffer(pPin, ulPinLen) + + logParam(hSession) + logParam(userType) + logParamBufHide(pPin, ulPinLen) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession = CSession::GetSessionFromID(hSession); + if (pSession == nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + if (userType != CKU_SO && userType != CKU_USER) + throw p11_error(CKR_USER_TYPE_INVALID); + + pSession->Login(userType, pPin, ulPinLen); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_Logout(CK_SESSION_HANDLE hSession) { + init_p11_func + std::unique_lock lock(p11Mutex); + + logParam(hSession) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession = CSession::GetSessionFromID(hSession); + if (pSession == nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + if (pSession->pSlot->User == CKU_NOBODY) + throw p11_error(CKR_USER_NOT_LOGGED_IN); + + pSession->Logout(); + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_SetAttributeValue(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount) { + init_p11_func + std::unique_lock lock(p11Mutex); + + logParam(hSession) + logParam(hObject) + logParam(pTemplate) + logParam(ulCount) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession =CSession::GetSessionFromID(hSession); + + if (pSession == nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + pSession->SetAttributeValue(hObject, pTemplate, ulCount); + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; + +} + +CK_RV CK_ENTRY C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkInBuffer(pData, ulDataLen) +// checkOutArray(pSignature, pulSignatureLen) +// checkInBuffer(pData, ulDataLen) +// checkOutArray(pSignature, pulSignatureLen) + + logParam(hSession) + logParamBuf(pData, ulDataLen) + logParamBuf(pSignature, pulSignatureLen) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession =CSession::GetSessionFromID(hSession); + + if (pSession == nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + ByteArray Signature(pSignature,*pulSignatureLen); + ByteArray input(pData, ulDataLen); + pSession->Sign(input, Signature); + *pulSignatureLen = (CK_ULONG)Signature.size(); + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,CK_ULONG_PTR pulSignatureLen) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkOutArray(pSignature, pulSignatureLen) + + logParam(hSession) + logParamBuf(pSignature, pulSignatureLen) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession =CSession::GetSessionFromID(hSession); + + if (pSession == nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + if (!pSession->pSignMechanism->SignSupportMultipart()) + throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); + + ByteArray Signature(pSignature,*pulSignatureLen); + pSession->SignFinal(Signature); + *pulSignatureLen = (CK_ULONG)Signature.size(); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkInPtr(pMechanism) + + logParam(hSession) + logParam(pMechanism) + logParam(hKey) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession =CSession::GetSessionFromID(hSession); + + if (pSession == nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + + if (!CheckMechanismParam(pMechanism)) + throw p11_error(CKR_MECHANISM_PARAM_INVALID); + + pSession->SignInit(pMechanism, hKey); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} +CK_RV CK_ENTRY C_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkInBuffer(pPart, ulPartLen) + + logParam(hSession) + logParamBuf(pPart, ulPartLen) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession =CSession::GetSessionFromID(hSession); + + if (pSession == nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + if (!pSession->pSignMechanism->SignSupportMultipart()) + throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); + + ByteArray input(pPart, ulPartLen); + pSession->SignUpdate(input); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_SignRecoverInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkInPtr(pMechanism) + + logParam(hSession) + logParam(pMechanism) + logParam(hKey) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession =CSession::GetSessionFromID(hSession); + + if (pSession == nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + if (!CheckMechanismParam(pMechanism)) + throw p11_error(CKR_MECHANISM_PARAM_INVALID); + + pSession->SignRecoverInit(pMechanism, hKey); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkInBuffer(pData, ulDataLen) +// checkOutArray(pSignature, pulSignatureLen) + + logParam(hSession) + logParamBuf(pData, ulDataLen) + logParamBuf(pSignature, pulSignatureLen) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession =CSession::GetSessionFromID(hSession); + + if (pSession == nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + ByteArray Signature(pSignature,*pulSignatureLen); + ByteArray input(pData, ulDataLen); + pSession->SignRecover(input, Signature); + *pulSignatureLen = (CK_ULONG)Signature.size(); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_VerifyRecoverInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkInPtr(pMechanism) + + logParam(hSession) + logParam(pMechanism) + logParam(hKey) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession =CSession::GetSessionFromID(hSession); + + if (pSession == nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + + if (!CheckMechanismParam(pMechanism)) + throw p11_error(CKR_MECHANISM_PARAM_INVALID); + + pSession->VerifyRecoverInit(pMechanism, hKey); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_VerifyRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkOutArray(pData, pulDataLen) +// checkInBuffer(pSignature, ulSignatureLen) + + logParam(hSession) + logParamBuf(pSignature, ulSignatureLen) + logParamBuf(pData, pulDataLen) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession =CSession::GetSessionFromID(hSession); + + if (pSession == nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + ByteArray Data(pData,*pulDataLen); + ByteArray input(pSignature, ulSignatureLen); + pSession->VerifyRecover(input, Data); + *pulDataLen = (CK_ULONG)Data.size(); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_VerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkInPtr(pMechanism) + + logParam(hSession) + logParam(pMechanism) + logParam(hKey) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession =CSession::GetSessionFromID(hSession); + + if (pSession == nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + if (!CheckMechanismParam(pMechanism)) + throw p11_error(CKR_MECHANISM_PARAM_INVALID); + + pSession->VerifyInit(pMechanism, hKey); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkInBuffer(pData, ulDataLen) +// checkInBuffer(pSignature, ulSignatureLen) + + logParam(hSession) + logParamBuf(pData, ulDataLen) + logParamBuf(pSignature, ulSignatureLen) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession =CSession::GetSessionFromID(hSession); + + if (pSession == nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + ByteArray input(pData, ulDataLen); + ByteArray signature(pSignature, ulSignatureLen); + pSession->Verify(input, signature); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_VerifyUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkInBuffer(pData, ulDataLen) + + logParam(hSession) + logParamBuf(pData, ulDataLen) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession =CSession::GetSessionFromID(hSession); + + if (pSession == nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + if (!pSession->pVerifyMechanism->VerifySupportMultipart()) + throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); + + ByteArray input(pData, ulDataLen); + pSession->VerifyUpdate(input); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_VerifyFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkInBuffer(pSignature, ulSignatureLen) + + logParam(hSession) + logParamBuf(pSignature, ulSignatureLen) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession =CSession::GetSessionFromID(hSession); + + if (pSession == nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + if (!pSession->pVerifyMechanism->VerifySupportMultipart()) + throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); + + ByteArray input(pSignature, ulSignatureLen); + pSession->VerifyFinal(input); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen) { + init_p11_func + + return CKR_FUNCTION_NOT_SUPPORTED; + +// std::unique_lock lock(p11Mutex); +// +//// checkInBuffer(pData, ulDataLen) +//// checkOutArray(pEncryptedData, pulEncryptedDataLen) +// +// logParam(hSession) +// logParamBuf(pData, ulDataLen) +// logParamBuf(pEncryptedData, pulEncryptedDataLen) +// +// if (!bP11Initialized) +// throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); +// +// std::shared_ptr pSession = CSession::GetSessionFromID(hSession); +// +// if (pSession == nullptr) +// throw p11_error(CKR_SESSION_HANDLE_INVALID); +// +// ByteArray EncryptedData(pEncryptedData, *pulEncryptedDataLen); +// ByteArray input(pData, ulDataLen); +// pSession->Encrypt(input, EncryptedData); +// *pulEncryptedDataLen = (CK_ULONG)EncryptedData.size(); +// +// return CKR_OK; + exit_p11_func +// return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_EncryptFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pEncryptedData,CK_ULONG_PTR pulEncryptedDataLen) { + init_p11_func + + return CKR_FUNCTION_NOT_SUPPORTED; + +// std::unique_lock lock(p11Mutex); +// +//// checkOutArray(pEncryptedData, pulEncryptedDataLen) +// +// logParam(hSession) +// logParamBuf(pEncryptedData, pulEncryptedDataLen) +// +// if (!bP11Initialized) +// throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); +// +// std::shared_ptr pSession = CSession::GetSessionFromID(hSession); +// +// if (pSession == nullptr) +// throw p11_error(CKR_SESSION_HANDLE_INVALID); +// +// if (!pSession->pEncryptMechanism->EncryptSupportMultipart()) +// throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); +// +// ByteArray EncryptedData(pEncryptedData, *pulEncryptedDataLen); +// pSession->EncryptFinal(EncryptedData); +// *pulEncryptedDataLen = (CK_ULONG)EncryptedData.size(); +// +// return CKR_OK; + exit_p11_func +// return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { + init_p11_func + + return CKR_FUNCTION_NOT_SUPPORTED; + +// std::unique_lock lock(p11Mutex); +// +//// checkInPtr(pMechanism) +// +// logParam(hSession) +// logParam(pMechanism) +// logParam(hKey) +// +// if (!bP11Initialized) +// throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); +// +// std::shared_ptr pSession =CSession::GetSessionFromID(hSession); +// +// if (pSession == nullptr) +// throw p11_error(CKR_SESSION_HANDLE_INVALID); +// +// if (!CheckMechanismParam(pMechanism)) +// throw p11_error(CKR_MECHANISM_PARAM_INVALID); +// +// pSession->EncryptInit(pMechanism, hKey); +// +// return CKR_OK; + exit_p11_func +// return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_EncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen) { + init_p11_func + + return CKR_FUNCTION_NOT_SUPPORTED; + +// std::unique_lock lock(p11Mutex); +// +//// checkInBuffer(pPart, ulPartLen) +//// checkOutArray(pEncryptedPart, pulEncryptedPartLen) +// +// logParam(hSession) +// logParamBuf(pPart, ulPartLen) +// logParamBuf(pEncryptedPart, pulEncryptedPartLen) +// +// if (!bP11Initialized) +// throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); +// +// std::shared_ptr pSession =CSession::GetSessionFromID(hSession); +// +// if (pSession == nullptr) +// throw p11_error(CKR_SESSION_HANDLE_INVALID); +// +// if (!pSession->pEncryptMechanism->EncryptSupportMultipart()) +// throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); +// +// ByteArray EncryptedPart(pEncryptedPart, *pulEncryptedPartLen); +// ByteArray input(pPart, ulPartLen); +// pSession->EncryptUpdate(input, EncryptedPart); +// *pulEncryptedPartLen = (CK_ULONG)EncryptedPart.size(); +// +// return CKR_OK; + exit_p11_func +// return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_Decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) { + init_p11_func + return CKR_FUNCTION_NOT_SUPPORTED; + +// std::unique_lock lock(p11Mutex); +// +//// checkInBuffer(pEncryptedData, ulEncryptedDataLen) +//// checkOutArray(pData, pulDataLen) +// +// logParam(hSession) +// logParamBuf(pEncryptedData, ulEncryptedDataLen) +// logParamBuf(pData, pulDataLen) +// +// if (!bP11Initialized) +// throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); +// +// std::shared_ptr pSession =CSession::GetSessionFromID(hSession); +// +// if (pSession == nullptr) +// throw p11_error(CKR_SESSION_HANDLE_INVALID); +// +// ByteArray Data(pData, *pulDataLen); +// ByteArray input(pEncryptedData, ulEncryptedDataLen); +// pSession->Decrypt(input, Data); +// *pulDataLen = (CK_ULONG)Data.size(); +// +// return CKR_OK; + exit_p11_func +// return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_DecryptFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG_PTR pulDataLen) { + init_p11_func + + return CKR_FUNCTION_NOT_SUPPORTED; + +// std::unique_lock lock(p11Mutex); +// +//// checkOutArray(pData, pulDataLen) +// +// logParam(hSession) +// logParamBuf(pData, pulDataLen) +// +// if (!bP11Initialized) +// throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); +// +// std::shared_ptr pSession =CSession::GetSessionFromID(hSession); +// +// if (pSession == nullptr) +// throw p11_error(CKR_SESSION_HANDLE_INVALID); +// +// if (!pSession->pDecryptMechanism->DecryptSupportMultipart()) +// throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); +// +// ByteArray Data(pData, *pulDataLen); +// pSession->DecryptFinal(Data); +// *pulDataLen = (CK_ULONG)Data.size(); +// +// return CKR_OK; + exit_p11_func +// return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_DecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { + init_p11_func + + return CKR_FUNCTION_NOT_SUPPORTED; + +// std::unique_lock lock(p11Mutex); +// +//// checkInPtr(pMechanism) +// +// logParam(hSession) +// logParam(pMechanism) +// logParam(hKey) +// +// if (!bP11Initialized) +// throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); +// +// std::shared_ptr pSession =CSession::GetSessionFromID(hSession); +// +// if (pSession == nullptr) +// throw p11_error(CKR_SESSION_HANDLE_INVALID); +// +// +// if (!CheckMechanismParam(pMechanism)) +// throw p11_error(CKR_MECHANISM_PARAM_INVALID); +// +// pSession->DecryptInit(pMechanism, hKey); +// +// return CKR_OK; + exit_p11_func +// return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_DecryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) { + init_p11_func + + return CKR_FUNCTION_NOT_SUPPORTED; + +// std::unique_lock lock(p11Mutex); +// +//// checkInBuffer(pEncryptedPart, ulEncryptedPartLen) +//// checkOutArray(pPart, pulPartLen) +// +// logParam(hSession) +// logParamBuf(pEncryptedPart, ulEncryptedPartLen) +// logParamBuf(pPart, pulPartLen) +// +// if (!bP11Initialized) +// throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); +// +// std::shared_ptr pSession =CSession::GetSessionFromID(hSession); +// +// if (pSession == nullptr) +// throw p11_error(CKR_SESSION_HANDLE_INVALID); +// +// if (!pSession->pDecryptMechanism->DecryptSupportMultipart()) +// throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); +// +// ByteArray Part(pPart, *pulPartLen); +// ByteArray input(pEncryptedPart, ulEncryptedPartLen); +// pSession->DecryptUpdate(input, Part); +// *pulPartLen = (CK_ULONG)Part.size(); +// +// return CKR_OK; + exit_p11_func +// return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved) { + init_p11_func + +// checkOutPtr(pSlot) + + logParam(flags) + logParam(pSlot) + logParam(pReserved) + + if (pReserved != NULL) + throw p11_error(CKR_ARGUMENTS_BAD); + + if (flags != 0 && flags != CKF_DONT_BLOCK) + throw p11_error(CKR_ARGUMENTS_BAD); + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + if (flags & CKF_DONT_BLOCK) { + std::unique_lock lock(p11Mutex); + //CSyncroLocker lock(p11EventMutex); + SlotMap::iterator it=CSlot::g_mSlots.begin(); + while (it!=CSlot::g_mSlots.end()) { + if (it->second->lastEvent!=SE_NoEvent) { + *pSlot=it->second->hSlot; + it->second->lastEvent=SE_NoEvent; + return CKR_OK; + } + it++; + } + throw p11_error(CKR_NO_EVENT); + } + + while (1) { + p11slotEvent.wait(); + //CSyncroLocker lock(p11EventMutex); + if (!bP11Initialized) { + *pSlot=0; + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + } + SlotMap::iterator it=CSlot::g_mSlots.begin(); + while (it!=CSlot::g_mSlots.end()) { + if (it->second->lastEvent!=SE_NoEvent) { + *pSlot=it->second->hSlot; + it->second->lastEvent=SE_NoEvent; + return CKR_OK; + } + it++; + } + } + + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen) { + init_p11_func + + logParam(hSession) + logParamBuf(pSeed, ulSeedLen) + + throw p11_error(CKR_RANDOM_SEED_NOT_SUPPORTED); + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_GenerateRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR RandomData, CK_ULONG ulRandomLen) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkOutBuffer(RandomData, ulRandomLen) + + logParam(hSession) + logParamBuf(RandomData, ulRandomLen) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession =CSession::GetSessionFromID(hSession); + + if (pSession == nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + ByteArray input(RandomData, ulRandomLen); + pSession->GenerateRandom(input); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_InitPIN(CK_SESSION_HANDLE hSession,CK_CHAR_PTR pPin,CK_ULONG ulPinLen) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkInBuffer(pPin,ulPinLen); + + logParam(hSession) + logParamBufHide(pPin, ulPinLen) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession =CSession::GetSessionFromID(hSession); + + if (pSession == nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + ByteArray input(pPin, ulPinLen); + pSession->InitPIN(input); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_SetPIN(CK_SESSION_HANDLE hSession,CK_CHAR_PTR pOldPin,CK_ULONG ulOldLen,CK_CHAR_PTR pNewPin,CK_ULONG ulNewLen) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkInBuffer(pOldPin,ulOldLen); +// checkInBuffer(pNewPin,ulNewLen); + + logParam(hSession) + logParamBufHide(pOldPin, ulOldLen) + logParamBufHide(pNewPin, ulNewLen) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession =CSession::GetSessionFromID(hSession); + + if (pSession == nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + ByteArray inputOld(pOldPin, ulOldLen); + ByteArray inputNew(pNewPin, ulNewLen); + pSession->SetPIN(inputOld, inputNew); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_GetObjectSize(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,CK_ULONG_PTR pulSize) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkOutPtr(pulSize); + + logParam(hSession) + logParam(hObject) + logParam(pulSize) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession =CSession::GetSessionFromID(hSession); + + if (pSession == nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + *pulSize = pSession->GetObjectSize(hObject); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_GetOperationState(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pOperationState,CK_ULONG_PTR pulOperationStateLen) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkOutArray(pOperationState, pulOperationStateLen) + + logParam(hSession) + logParamBuf(pOperationState, pulOperationStateLen) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession =CSession::GetSessionFromID(hSession); + + if (pSession == nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + ByteArray OperationState(pOperationState,*pulOperationStateLen); + pSession->GetOperationState(OperationState); + *pulOperationStateLen = (CK_ULONG)OperationState.size(); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +CK_RV CK_ENTRY C_SetOperationState(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pOperationState,CK_ULONG ulOperationStateLen,CK_OBJECT_HANDLE hEncryptionKey,CK_OBJECT_HANDLE hAuthenticationKey) { + init_p11_func + std::unique_lock lock(p11Mutex); + +// checkInBuffer(pOperationState, ulOperationStateLen) + + logParam(hSession) + logParamBuf(pOperationState, ulOperationStateLen) + logParam(hEncryptionKey) + logParam(hAuthenticationKey) + + if (!bP11Initialized) + throw p11_error(CKR_CRYPTOKI_NOT_INITIALIZED); + + std::shared_ptr pSession =CSession::GetSessionFromID(hSession); + + if (pSession == nullptr) + throw p11_error(CKR_SESSION_HANDLE_INVALID); + + if (hEncryptionKey != CK_INVALID_HANDLE) + throw p11_error(CKR_KEY_NOT_NEEDED); + if (hAuthenticationKey != CK_INVALID_HANDLE) + throw p11_error(CKR_KEY_NOT_NEEDED); + + ByteArray input(pOperationState, ulOperationStateLen); + pSession->SetOperationState(input); + + return CKR_OK; + exit_p11_func + return CKR_GENERAL_ERROR; +} + +#define unsupported \ +{ \ + init_p11_func \ + LOG_ERROR("%s","Funzione non supportata!!"); \ + throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); \ + exit_p11_func \ + return CKR_FUNCTION_NOT_SUPPORTED; \ +} + +CK_RV CK_ENTRY C_InitToken(CK_SLOT_ID slotID,CK_CHAR_PTR pPin,CK_ULONG ulPinLen,CK_UTF8CHAR_PTR pLabel) unsupported +CK_RV CK_ENTRY C_CopyObject(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phNewObject) unsupported +CK_RV CK_ENTRY C_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey) unsupported +CK_RV CK_ENTRY C_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen) unsupported +CK_RV CK_ENTRY C_DecryptDigestUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) unsupported +CK_RV CK_ENTRY C_SignEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, CK_ULONG_PTR pulEncryptedPartLen) unsupported +CK_RV CK_ENTRY C_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) unsupported +CK_RV CK_ENTRY C_WrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen) unsupported +CK_RV CK_ENTRY C_UnwrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey) unsupported +CK_RV CK_ENTRY C_DeriveKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey) unsupported +CK_RV CK_ENTRY C_GetFunctionStatus(CK_SESSION_HANDLE hSession) unsupported +CK_RV CK_ENTRY C_CancelFunction(CK_SESSION_HANDLE hSession) unsupported + + +char *getAttributeName(unsigned long dwId) { + switch (dwId) { + case 0x00000000: + return("CKA_CLASS"); + case 0x00000001: + return("CKA_TOKEN"); + case 0x00000002: + return("CKA_PRIVATE"); + case 0x00000003: + return("CKA_LABEL"); + case 0x00000010: + return("CKA_APPLICATION"); + case 0x00000011: + return("CKA_VALUE"); + case 0x00000012: + return("CKA_OBJECT_ID"); + case 0x00000080: + return("CKA_CERTIFICATE_TYPE"); + case 0x00000081: + return("CKA_ISSUER"); + case 0x00000082: + return("CKA_SERIAL_NUMBER"); + case 0x00000083: + return("CKA_AC_ISSUER"); + case 0x00000084: + return("CKA_OWNER"); + case 0x00000085: + return("CKA_ATTR_TYPES"); + case 0x00000086: + return("CKA_TRUSTED"); + case 0x00000100: + return("CKA_KEY_TYPE"); + case 0x00000101: + return("CKA_SUBJECT"); + case 0x00000102: + return("CKA_ID"); + case 0x00000103: + return("CKA_SENSITIVE"); + case 0x00000104: + return("CKA_ENCRYPT"); + case 0x00000105: + return("CKA_DECRYPT"); + case 0x00000106: + return("CKA_WRAP"); + case 0x00000107: + return("CKA_UNWRAP"); + case 0x00000108: + return("CKA_SIGN"); + case 0x00000109: + return("CKA_SIGN_RECOVER"); + case 0x0000010A: + return("CKA_VERIFY"); + case 0x0000010B: + return("CKA_VERIFY_RECOVER"); + case 0x0000010C: + return("CKA_DERIVE"); + case 0x00000110: + return("CKA_START_DATE"); + case 0x00000111: + return("CKA_END_DATE"); + case 0x00000120: + return("CKA_MODULUS"); + case 0x00000121: + return("CKA_MODULUS_BITS"); + case 0x00000122: + return("CKA_PUBLIC_EXPONENT"); + case 0x00000123: + return("CKA_PRIVATE_EXPONENT"); + case 0x00000124: + return("CKA_PRIME_1"); + case 0x00000125: + return("CKA_PRIME_2"); + case 0x00000126: + return("CKA_EXPONENT_1"); + case 0x00000127: + return("CKA_EXPONENT_2"); + case 0x00000128: + return("CKA_COEFFICIENT"); + case 0x00000130: + return("CKA_PRIME"); + case 0x00000131: + return("CKA_SUBPRIME"); + case 0x00000132: + return("CKA_BASE"); + case 0x00000133: + return("CKA_PRIME_BITS"); + case 0x00000134: + return("CKA_SUB_PRIME_BITS"); + case 0x00000160: + return("CKA_VALUE_BITS"); + case 0x00000161: + return("CKA_VALUE_LEN"); + case 0x00000162: + return("CKA_EXTRACTABLE"); + case 0x00000163: + return("CKA_LOCAL"); + case 0x00000164: + return("CKA_NEVER_EXTRACTABLE"); + case 0x00000165: + return("CKA_ALWAYS_SENSITIVE"); + case 0x00000166: + return("CKA_KEY_GEN_MECHANISM"); + case 0x00000170: + return("CKA_MODIFIABLE"); + case 0x00000180: + return("CKA_EC_PARAMS"); + case 0x00000181: + return("CKA_EC_POINT"); + case 0x00000200: + return("CKA_SECONDARY_AUTH"); + case 0x00000201: + return("CKA_AUTH_PIN_FLAGS"); + case 0x00000300: + return("CKA_HW_FEATURE_TYPE"); + case 0x00000301: + return("CKA_RESET_ON_INIT"); + case 0x00000302: + return("CKA_HAS_RESET"); + case 0x80000000: + return("CKA_VENDOR_DEFINED"); + case 0x80000001: + return("CKA_SM"); + case 0x80000002: + return("CKA_SM_PUB"); + } + return("UNKNOWN"); +} + + + diff --git a/libcie-pkcs11/PKCS11/PKCS11Functions.h b/libcie-pkcs11/PKCS11/PKCS11Functions.h index 7ebb1978..5d7405e3 100644 --- a/libcie-pkcs11/PKCS11/PKCS11Functions.h +++ b/libcie-pkcs11/PKCS11/PKCS11Functions.h @@ -1,74 +1,74 @@ -#pragma once - -#include "cryptoki.h" - -#ifdef WIN32 -#include -#else -#include -#endif - -#define MAXVAL 0xffffff -#define MAXSESSIONS MAXVAL - -#ifdef WIN32 -#define CK_ENTRY __declspec(dllexport) -#else -#define CK_ENTRY -#endif -#define LIBRARY_VERSION_MAJOR 2 -#define LIBRARY_VERSION_MINOR 0 - -#define PIN_LEN 8 -#define USER_PIN_ID 0x10 - -#ifdef WIN32 - -#define init_p11_func \ - CFuncCallInfo info(__FUNCTION__, Log); \ - try { - -#define exit_p11_func } \ - catch (p11_error &p11Err) { \ - OutputDebugString("%s", "EXCLOG->"); \ - OutputDebugString("%s", p11Err.what()); \ - OutputDebugString("%s", "<-EXCLOG");\ - return p11Err.getP11ErrorCode(); \ - } \ - catch (std::exception &err) { \ - OutputDebugString("%s", "EXCLOG->"); \ - OutputDebugString("%s", err.what()); \ - OutputDebugString("%s", "<-EXCLOG");\ - return CKR_GENERAL_ERROR; \ - } \ -catch (...) { return CKR_GENERAL_ERROR; } - -#else - -#define init_p11_func \ - CFuncCallInfo info(__FUNCTION__, Log); \ - try { - -#define exit_p11_func } \ -catch (p11_error &p11Err) { \ -Log.write(p11Err.what()); \ -OutputDebugString("%s", "EXCLOG->"); \ -OutputDebugString("EXC: %s", p11Err.what()); \ -OutputDebugString("%s", "<-EXCLOG");\ -Log.writePure("P11Error: %x", p11Err.getP11ErrorCode()); \ -return p11Err.getP11ErrorCode(); \ -} \ -catch (std::exception &err) { \ -Log.write(err.what()); \ -OutputDebugString("%s", "EXCLOG->"); \ -OutputDebugString("EXC: %s", err.what()); \ -OutputDebugString("%s", "<-EXCLOG");\ -return CKR_GENERAL_ERROR; \ -} \ -catch (...) { Log.writePure("%s, CKR_GENERAL_ERROR", __FUNCTION__); return CKR_GENERAL_ERROR; } - -#endif - -extern "C" { - CK_RV CK_ENTRY C_UpdateSlotList(); -} +#pragma once + +#include "cryptoki.h" + +#ifdef WIN32 +#include +#else +#include +#endif + +#define MAXVAL 0xffffff +#define MAXSESSIONS MAXVAL + +#ifdef WIN32 +#define CK_ENTRY __declspec(dllexport) +#else +#define CK_ENTRY +#endif +#define LIBRARY_VERSION_MAJOR 2 +#define LIBRARY_VERSION_MINOR 0 + +#define PIN_LEN 8 +#define USER_PIN_ID 0x10 + +#ifdef WIN32 + +#define init_p11_func \ + CFuncCallInfo info(__FUNCTION__, Log); \ + try { + +#define exit_p11_func } \ + catch (p11_error &p11Err) { \ + OutputDebugString("EXCLOG->"); \ + OutputDebugString(p11Err.what()); \ + OutputDebugString("<-EXCLOG");\ + return p11Err.getP11ErrorCode(); \ + } \ + catch (std::exception &err) { \ + OutputDebugString("EXCLOG->"); \ + OutputDebugString(err.what()); \ + OutputDebugString("<-EXCLOG");\ + return CKR_GENERAL_ERROR; \ + } \ +catch (...) { return CKR_GENERAL_ERROR; } + +#else + +#include "../LOGGER/Logger.h" + +using namespace CieIDLogger; + +#define init_p11_func \ + LOG_INFO("[PKCS11] %s", __FUNCTION__); \ + try { + +#define exit_p11_func } \ +catch (p11_error &p11Err) { \ +LOG_ERROR("[PKCS11] EXC: %s", p11Err.what()); \ +LOG_ERROR("[PKCS11] P11Error: %x", p11Err.getP11ErrorCode()); \ +return p11Err.getP11ErrorCode(); \ +} \ +catch (std::exception &err) { \ +LOG_ERROR("EXCLOG->"); \ +LOG_ERROR("EXC: %s", err.what()); \ +LOG_ERROR("<-EXCLOG");\ +return CKR_GENERAL_ERROR; \ +} \ +catch (...) { LOG_ERROR("%s, CKR_GENERAL_ERROR", __FUNCTION__); return CKR_GENERAL_ERROR; } + +#endif + +extern "C" { + CK_RV CK_ENTRY C_UpdateSlotList(); +} diff --git a/libcie-pkcs11/PKCS11/Slot.cpp b/libcie-pkcs11/PKCS11/Slot.cpp index 28813c10..c72c137e 100644 --- a/libcie-pkcs11/PKCS11/Slot.cpp +++ b/libcie-pkcs11/PKCS11/Slot.cpp @@ -1,700 +1,702 @@ - -#include "Slot.h" -#include "PKCS11Functions.h" -#include "../PCSC/Token.h" - -#include "CardTemplate.h" -#include "../Util/util.h" -#include "../Util/SyncroEvent.h" -#include -#include - -extern CLog Log; - -extern std::mutex p11Mutex; -extern auto_reset_event p11slotEvent; -extern bool bP11Terminate; -extern bool bP11Initialized; - -extern uint8_t NXP_ATR[]; -extern uint8_t Gemalto_ATR[]; -extern uint8_t Gemalto2_ATR[]; -extern uint8_t STM_ATR[]; -extern uint8_t STM2_ATR[]; - -extern ByteArray baNXP_ATR; -extern ByteArray baGemalto_ATR; -extern ByteArray baGemalto2_ATR; -extern ByteArray baSTM_ATR; -extern ByteArray baSTM2_ATR; -extern ByteArray baSTM3_ATR; - -namespace p11 { - -DWORD CSlot::dwSlotCnt = 0; -SlotMap CSlot::g_mSlots; -std::thread CSlot::Thread; -CCardContext *CSlot::ThreadContext = NULL; -bool CSlot::bMonitorUpdate = false; - -CSlot::CSlot(const char *szReader) { - szName = szReader; - lastEvent = SE_NoEvent; - bUpdated = 0; - User = CKU_NOBODY; - dwP11ObjCnt = 0; - dwSessionCount = 0; - pTemplate = NULL; - //slotMutex.Create(mutexName(szReader)); - pSerialTemplate = NULL; - hCard = NULL; -} - -CSlot::~CSlot() { - Final(); -} - -CK_SLOT_ID CSlot::GetNewSlotID() { - init_func - return ++dwSlotCnt; -} - -static DWORD slotMonitor(SlotMap *pSlotMap) { - while (true) { - CCardContext Context; - CSlot::ThreadContext = &Context; - size_t dwSlotNum = pSlotMap->size(); - std::vector state(dwSlotNum); - std::vector> slot(dwSlotNum); - size_t i = 0; - DWORD ris; - { - std::unique_lock lock(p11Mutex); - for (SlotMap::const_iterator it = pSlotMap->begin(); it != pSlotMap->end(); it++, i++) { - if (!bP11Initialized) { - CSlot::ThreadContext = NULL; - return 0; - } - - state[i].szReader = it->second->szName.c_str(); - slot[i] = it->second; - if ((ris = SCardGetStatusChange(Context, 0, &state[i], 1)) != S_OK) { - if (ris != SCARD_E_TIMEOUT) { - Log.write("Errore nella SCardGetStatusChange - %08X", ris); - // non uso la ExitThread!!! - // altrimenti non chiamo i distruttori, e mi rimane tutto appeso - // SOPRATTUTTO il p11Mutex - CSlot::ThreadContext = NULL; - return 1; - } - } - state[i].dwCurrentState = state[i].dwEventState & (~SCARD_STATE_CHANGED); - } - } - CSlot::bMonitorUpdate = false; - while (true) { - Context.validate(); - ris = SCardGetStatusChange(Context, 1000, state.data(), (DWORD)dwSlotNum); - if (ris != S_OK) { - if (CSlot::bMonitorUpdate || ris == SCARD_E_SYSTEM_CANCELLED || ris == SCARD_E_SERVICE_STOPPED || ris == SCARD_E_INVALID_HANDLE || ris == ERROR_INVALID_HANDLE) { - Log.write("Monitor Update"); - break; - } - if (ris == SCARD_E_CANCELLED || bP11Terminate || !bP11Initialized) { - Log.write("Terminate"); - p11slotEvent.set(); - CSlot::ThreadContext = NULL; - // no exitThread, vedi sopra; - return 0; - } - if (ris != SCARD_E_TIMEOUT && ris != SCARD_E_NO_READERS_AVAILABLE) { - Log.write("Errore nella SCardGetStatusChange - %08X", ris); - p11slotEvent.set(); - CSlot::ThreadContext = NULL; - // no exitThread, vedi sopra; - return 1; - } - if (ris == SCARD_E_NO_READERS_AVAILABLE) { - Log.write("Nessun lettore connesso - %08X", ris); - CSlot::ThreadContext = NULL; - // no exitThread, vedi sopra; - return 1; - } - } - if (bP11Terminate || !bP11Initialized) { - Log.write("Terminate"); - p11slotEvent.set(); - CSlot::ThreadContext = NULL; - // no exitThread, vedi sopra; - return 0; - } - - for (size_t i = 0; i < dwSlotNum; i++) { - if ((state[i].dwCurrentState & SCARD_STATE_PRESENT) && - ((state[i].dwEventState & SCARD_STATE_EMPTY) || - (state[i].dwEventState & SCARD_STATE_UNAVAILABLE))) { - // una carta è stata estratta!! - // sincronizzo sul mutex principale p11 - // le funzioni attualmente in esecuzione che vanno sulla - // carta falliranno miseramente, ma se levi la carta - // mentre sto firmado mica è colpa mia! - - std::unique_lock lock(p11Mutex); - - slot[i]->lastEvent = SE_Removed; - slot[i]->Final(); - slot[i]->baATR.clear(); - p11slotEvent.set(); - } - if (((state[i].dwCurrentState & SCARD_STATE_UNAVAILABLE) || - (state[i].dwCurrentState & SCARD_STATE_EMPTY)) && - (state[i].dwEventState & SCARD_STATE_PRESENT)) { - // una carta è stata inserita!! - std::unique_lock lock(p11Mutex); - - slot[i]->lastEvent = SE_Inserted; - ByteArray ba; - slot[i]->GetATR(ba); - p11slotEvent.set(); - } - state[i].dwCurrentState = state[i].dwEventState & (~SCARD_STATE_CHANGED); - } - } - CSlot::ThreadContext = NULL; - } - // no exitThread, vedi sopra; - return 0; -} - -CK_SLOT_ID CSlot::AddSlot(std::shared_ptr pSlot) { - init_func - pSlot->hSlot = (CK_SLOT_ID)pSlot->GetNewSlotID(); - auto id = pSlot->hSlot; - g_mSlots.insert(std::make_pair(pSlot->hSlot, std::move(pSlot))); - return id; -} - -void CSlot::DeleteSlot(CK_SLOT_ID hSlotId) { - init_func - std::shared_ptr pSlot = GetSlotFromID(hSlotId); - - if (!pSlot) - throw p11_error(CKR_SLOT_ID_INVALID); - - pSlot->CloseAllSessions(); - -// try { -// g_mSlots.erase(hSlotId); -// } catch (...) { -// printf("erase error"); -// } - - pSlot->Final(); -} - -std::shared_ptr CSlot::GetSlotFromReaderName(const char *name) { - init_func - for (SlotMap::iterator it = g_mSlots.begin(); it != g_mSlots.end(); it++) { - if (strcmp(it->second->szName.c_str(), name) == 0) { - return it->second; - } - } - return nullptr; -} - -std::shared_ptr CSlot::GetSlotFromID(CK_SLOT_ID hSlotId) { - init_func - SlotMap::const_iterator pPair; - pPair = g_mSlots.find(hSlotId); - if (pPair == g_mSlots.end()) { - return nullptr; - } - return pPair->second; -} - -void CSlot::DeleteSlotList() { - init_func - -// int i = 0; - - if (Thread.joinable()) - Thread.join(); - - // TODO: verificare se è il caso di usare un thread con join a tempo - - /*while (i<5) { - if (Thread.join(1000)==OK) - break; - i=i+1; - if (CSlot::ThreadContext!=NULL) - SCardCancel(*CSlot::ThreadContext); - } - if (i==5) { - Thread.terminateThread(); - }*/ - - SlotMap::iterator it = CSlot::g_mSlots.begin(); - while (it != CSlot::g_mSlots.end()) { - DeleteSlot(it->second->hSlot); - it++;// = CSlot::g_mSlots.begin(); - } -} - -void CSlot::InitSlotList() { - // la InitSlotList deve aggiornare la liste degli slot; - // cioè, deve aggiungere gli slot che non c'erano prima e - // cancellare quelli che non ci sono più - init_func - bool bMapChanged = false; - DWORD readersLen = 0; - - CCardContext Context; - - if (!bP11Initialized) - return; - - auto ris = SCardListReaders(Context, NULL, NULL, &readersLen); - if (ris != S_OK) { - if (ris == SCARD_E_NO_READERS_AVAILABLE) - return; - throw windows_error(ris); - } - std::string readers; - readers.resize(readersLen + 1); - if ((ris = SCardListReaders(Context, NULL, &readers[0], &readersLen)) != SCARD_S_SUCCESS) - throw windows_error(ris); - - const char *szReaderName = readers.c_str(); - - while (*szReaderName != 0) { - if (!bP11Initialized) - return; - - // vediamo questo slot c'era già prima - Log.write("reader:%s", szReaderName); - std::shared_ptr pSlot = GetSlotFromReaderName(szReaderName); - if (pSlot == nullptr) { - auto pSlot = std::make_shared(szReaderName); -// CK_SLOT_ID hSlotID = - AddSlot(pSlot); - bMapChanged = true; - } - szReaderName = szReaderName + strnlen(szReaderName, readersLen) + 1; - } - // adesso vedo se tutti gli slot nella mappa ci sono ancora - for (SlotMap::iterator it = g_mSlots.begin(); it != g_mSlots.end(); it++) { - if (!bP11Initialized) - return; - - Log.write("%s", it->second->szName.c_str()); - const char *name = it->second->szName.c_str(); - - const char *szReaderName = readers.c_str(); - //char *szReaderName=szReaderAlloc; - bool bFound = false; - while (*szReaderName != 0) { - if (strcmp(name, szReaderName) == 0) { - bFound = true; - break; - } - szReaderName = szReaderName + strnlen(szReaderName, readersLen) + 1; - } - if (!bFound) { - CK_SLOT_ID ID = it->second->hSlot; - it--; - DeleteSlot(ID); - bMapChanged = true; - } - } - bMonitorUpdate = bMapChanged; - - if (!bP11Initialized) - return; - - if (!Thread.joinable()) - Thread = std::thread(slotMonitor, &g_mSlots); - - Log.write("InitSlotList ok"); -} - -bool CSlot::IsTokenPresent() { - init_func - SCARD_READERSTATE state; - memset(&state, 0, sizeof(SCARD_READERSTATE)); - state.szReader = szName.c_str(); - - Context.validate(); - bool retry = false; - while (true) { - DWORD ris = SCardGetStatusChange(Context, 0, &state, 1); - if (ris == S_OK) { - if ((state.dwEventState & SCARD_STATE_UNAVAILABLE) == SCARD_STATE_UNAVAILABLE) - throw p11_error(CKR_DEVICE_REMOVED); - if ((state.dwEventState & SCARD_STATE_PRESENT) == SCARD_STATE_PRESENT) - return true; - else - return false; - } else { - if (ris == SCARD_E_SERVICE_STOPPED || ris == SCARD_E_INVALID_HANDLE || ris == ERROR_INVALID_HANDLE) { - // devo prendere un nuovo context e riprovare - if (!retry) - retry = true; - else - throw windows_error(ris); - Context.renew(); - continue; - } - if (ris == SCARD_E_NO_READERS_AVAILABLE) - throw p11_error(CKR_DEVICE_REMOVED); - throw windows_error(ris); - } - } -} - -void CSlot::GetInfo(CK_SLOT_INFO_PTR pInfo) { - init_func - pInfo->flags = CKF_REMOVABLE_DEVICE | CKF_HW_SLOT; - // verifico che ci sia una carta inserita - - if (IsTokenPresent()) - pInfo->flags |= CKF_TOKEN_PRESENT; - - memset(pInfo->slotDescription, 0, 64); - size_t SDLen = min1(64, szName.size() - 1); - CryptoPP::memcpy_s(pInfo->slotDescription, 64, szName.c_str(), SDLen); - - memset(pInfo->manufacturerID, 0, 32); - // non so esattamente perchè, ma nella R1 il manufacturerID sono i primi 32 dello slotDescription - size_t MIDLen = min1(32, szName.size()); - CryptoPP::memcpy_s(pInfo->manufacturerID, 32, szName.c_str(), MIDLen); - - pInfo->hardwareVersion.major = 0; - pInfo->hardwareVersion.minor = 0; - - pInfo->firmwareVersion.major = 0; - pInfo->firmwareVersion.minor = 0; -} - -void CSlot::GetTokenInfo(CK_TOKEN_INFO_PTR pInfo) { - init_func - - if (pTemplate == nullptr) - pTemplate = CCardTemplate::GetTemplate(*this); - - if (pTemplate == nullptr) - throw p11_error(CKR_TOKEN_NOT_RECOGNIZED); - - memset(pInfo->label, 0, sizeof(pInfo->label)); - CryptoPP::memcpy_s((char*)pInfo->label, 32, pTemplate->szName.c_str(), std::min(pTemplate->szName.length(), sizeof(pInfo->label))); - memset(pInfo->manufacturerID, ' ', sizeof(pInfo->manufacturerID)); - - std::string manifacturer; - size_t position; - if (baATR.indexOf(baNXP_ATR, position)) - manifacturer = "NXP"; - else if ((baATR.indexOf(baGemalto_ATR, position)) || - (baATR.indexOf(baGemalto2_ATR, position))) - manifacturer = "Gemalto"; - else if ((baATR.indexOf(baSTM_ATR, position))) - manifacturer = "STM"; - else if ((baATR.indexOf(baSTM2_ATR, position))) - manifacturer = "STM2"; - else if ((baATR.indexOf(baSTM3_ATR, position))) - manifacturer = "STM3"; - else - throw p11_error(CKR_TOKEN_NOT_RECOGNIZED); - - CryptoPP::memcpy_s((char*)pInfo->manufacturerID, 32, manifacturer.c_str(), manifacturer.size()); - - if (baSerial.isEmpty() || pSerialTemplate != pTemplate) { - pSerialTemplate = pTemplate; - baSerial = pTemplate->FunctionList.templateGetSerial(*this); - } - - std::string model; - pTemplate->FunctionList.templateGetModel(*this, model); - - memset(pInfo->serialNumber, 0, sizeof(pInfo->serialNumber)); - size_t UIDsize = min1(sizeof(pInfo->serialNumber), baSerial.size()); - CryptoPP::memcpy_s(pInfo->serialNumber, 16, baSerial.data(), UIDsize); - - CryptoPP::memcpy_s((char*)pInfo->label + pTemplate->szName.length() + 1, sizeof(pInfo->label) - pTemplate->szName.length() - 1, baSerial.data(), baSerial.size()); - - memset(pInfo->model, 0, sizeof(pInfo->model)); - CryptoPP::memcpy_s(pInfo->model, 16, model.c_str(), min1(model.length(), sizeof(pInfo->model))); - - CK_FLAGS dwFlags; - pTemplate->FunctionList.templateGetTokenFlags(*this, dwFlags); - pInfo->flags = dwFlags; - - pInfo->ulTotalPublicMemory = CK_UNAVAILABLE_INFORMATION; - pInfo->ulTotalPrivateMemory = CK_UNAVAILABLE_INFORMATION; - pInfo->ulFreePublicMemory = CK_UNAVAILABLE_INFORMATION; - pInfo->ulFreePrivateMemory = CK_UNAVAILABLE_INFORMATION; - pInfo->ulMaxSessionCount = MAXSESSIONS; - size_t dwSessCount = SessionCount(); - - pInfo->ulSessionCount = (CK_ULONG)dwSessCount; - size_t dwRWSessCount = RWSessionCount(); - - pInfo->ulRwSessionCount = dwRWSessCount; - pInfo->ulMaxRwSessionCount = MAXSESSIONS; - - pInfo->ulMinPinLen = 8; - pInfo->ulMaxPinLen = 8; - - pInfo->hardwareVersion.major = 0; - pInfo->hardwareVersion.minor = 0; - - pInfo->firmwareVersion.major = 0; - pInfo->firmwareVersion.minor = 0; - - CryptoPP::memcpy_s((char*)pInfo->utcTime, 16, "1234567890123456", 16); // OK -} - -void CSlot::CloseAllSessions() { - init_func - - SessionMap::iterator it = CSession::g_mSessions.begin(); - while (it != CSession::g_mSessions.end()) { - if (it->second->pSlot.get() == this) { - CSession *pSession = it->second.get(); - it++; - CSession::DeleteSession(pSession->hSessionHandle); - } else it++; - } -} - -void CSlot::Init() { - init_func - if (!bUpdated) { - - if (pTemplate == nullptr) - pTemplate = CCardTemplate::GetTemplate(*this); - - - if (pTemplate == nullptr) - throw p11_error(CKR_TOKEN_NOT_RECOGNIZED); - - pTemplate->FunctionList.templateInitCard(pTemplateData, *this); - bUpdated = true; - } -} - -void CSlot::Final() { - if (bUpdated) { - // cancello i dati del template - pTemplate->FunctionList.templateFinalCard(pTemplateData); - pTemplate = NULL; - - baATR.clear(); - baSerial.clear(); - - P11Objects.clear(); - - // cancello tutte le sessioni - SessionMap::iterator it = CSession::g_mSessions.begin(); - while (it != CSession::g_mSessions.end()) { - if (it->second->pSlot.get() == this) { - it = CSession::g_mSessions.erase(it); - dwSessionCount--; - } else it++; - } - // dwSessionCount dovrebbe essere già a 0... - // ma per sicurezza lo setto a manina - - User = CKU_NOBODY; - dwSessionCount = 0; - bUpdated = false; - } -} - -std::shared_ptr CSlot::FindP11Object(CK_OBJECT_CLASS objClass, CK_ATTRIBUTE_TYPE attr, CK_BYTE *val, int valLen) { - init_func - for (DWORD i = 0; i < P11Objects.size(); i++) { - auto obj = P11Objects[i]; - if (obj->ObjClass == objClass) { - ByteArray *attrVal = obj->getAttribute(attr); - if (attrVal && attrVal->size() == valLen) { - if (memcmp(attrVal->data(), val, valLen) == 0) { - return obj; - } - } - } - } - return nullptr; -} - -void CSlot::AddP11Object(std::shared_ptr p11obj) { - init_func - p11obj->pSlot = this; - P11Objects.emplace_back(std::move(p11obj)); -} - -void CSlot::ClearP11Objects() { - init_func - P11Objects.clear(); - ObjP11Map.clear(); - HandleP11Map.clear(); -} - -void CSlot::DelP11Object(const std::shared_ptr& object) { - init_func - bool bFound = false; - for (P11ObjectVector::iterator it = P11Objects.begin(); it != P11Objects.end(); it++) { - if (*it == object) { - bFound = true; - P11Objects.erase(it); - break; - } - } - ER_ASSERT(bFound, ERR_FIND_OBJECT) - - ObjHandleMap::iterator itObj = ObjP11Map.find(object); - if (itObj != ObjP11Map.end()) { - HandleObjMap::iterator itHandle = HandleP11Map.find(itObj->second); - ObjP11Map.erase(itObj); - if (itHandle != HandleP11Map.end()) - HandleP11Map.erase(itHandle); - } -} - -size_t CSlot::SessionCount() { - init_func - return dwSessionCount; -} - -size_t CSlot::RWSessionCount() { - init_func - size_t dwRWSessCount = 0; - for (SessionMap::iterator it = CSession::g_mSessions.begin(); it != CSession::g_mSessions.end(); it++) { - if (it->second->pSlot.get() == this && (it->second->flags & CKF_RW_SESSION) != 0) - dwRWSessCount++; - } - return dwRWSessCount; -} - -CK_OBJECT_HANDLE CSlot::GetIDFromObject(const std::shared_ptr&pObject) { - init_func - - if (pObject->IsPrivate() && User != CKU_USER) - throw p11_error(CKR_USER_NOT_LOGGED_IN); - - ObjHandleMap::const_iterator pPair; - pPair = ObjP11Map.find(pObject); - if (pPair == ObjP11Map.end()) { - // non ho trovato l'oggetto nella mappa degli oggetti; - // devo aggiungerlo - - CK_OBJECT_HANDLE hObject = (CK_OBJECT_HANDLE)&pObject;//GetNewObjectID(); - ObjP11Map[pObject] = hObject; - HandleP11Map[hObject] = pObject; - return hObject; - } - return pPair->second; -} - -// CK_OBJECT_HANDLE CSlot::GetNewObjectID() { -// init_func -// return InterlockedIncrement(&dwP11ObjCnt); -// } - -void CSlot::DelObjectHandle(const std::shared_ptr& pObject) { - init_func - ObjHandleMap::iterator pPair; - pPair = ObjP11Map.find(pObject); - if (pPair != ObjP11Map.end()) { - HandleObjMap::iterator pPair2; - pPair2 = HandleP11Map.find(pPair->second); - if (pPair2 != HandleP11Map.end()) - HandleP11Map.erase(pPair2); - ObjP11Map.erase(pPair); - } -} - -std::shared_ptr CSlot::GetObjectFromID(CK_OBJECT_HANDLE hObjectHandle) { - init_func - HandleObjMap::const_iterator pPair; - pPair = HandleP11Map.find(hObjectHandle); - if (pPair == HandleP11Map.end()) - return nullptr; - - return pPair->second; -} - -void CSlot::Connect() { - init_func - DWORD dwProtocol; - - Context.validate(); - bool retry = false; - while (true) { - DWORD ris = SCardConnect(Context, szName.c_str(), SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, &hCard, &dwProtocol); - if (ris == SCARD_S_SUCCESS) { - return; - } else { - if (ris == SCARD_E_SERVICE_STOPPED || ris == SCARD_E_INVALID_HANDLE || ris == ERROR_INVALID_HANDLE) { - if (!retry) - retry = true; - else { - throw windows_error(ris); - } - Context.renew(); - } else { - if (ris != SCARD_S_SUCCESS) - throw windows_error(ris); - } - } - } -} - -#define SCARD_ATTR_VALUE(Class, Tag) ((((uint32_t)(Class)) << 16) | ((uint32_t)(Tag))) -#define SCARD_CLASS_ICC_STATE 9 /**< ICC State specific definitions */ -#define SCARD_ATTR_ATR_STRING SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0303) /**< Answer to reset (ATR) string. */ - - -ByteDynArray CSlot::GetATR() { - init_func - - DWORD atrLen = 40; - char ATR[40]; - long ret = SCardGetAttrib(this->hCard, SCARD_ATTR_ATR_STRING, (uint8_t*)ATR, &atrLen); - if(ret == SCARD_S_SUCCESS) { - Log.writeBinData((BYTE*)ATR, atrLen); - return ByteArray((BYTE*)ATR, atrLen); - } else { - Log.write("ATR Letto: -nessuna carta inserita-"); - return ByteArray(); - } -//readCIEType -// SCARD_READERSTATE state; -// state.szReader = this->szName.data(); -// long ret = SCardGetStatusChange(CSlot::Context, 0, &state, 1); -// -// printf("\nSCardGetStatusChange: %x\n", ret); -// -// if (state.cbAtr > 0) { -// Log.write("ATR Letto:"); -// if(state.cbAtr > 32) -// state.cbAtr = 32; -// -// Log.writeBinData(state.rgbAtr, state.cbAtr); -// return ByteArray(state.rgbAtr, state.cbAtr); -// } -// else { -// Log.write("ATR Letto: -nessuna carta inserita-"); -// return ByteArray(); -// } -} - -void CSlot::GetATR(ByteArray &ATR) { - init_func - if (baATR.size() != 0) { - ATR = baATR; - return; - } - baATR = GetATR(); - ATR = baATR; -} - -} + +#include "Slot.h" +#include "PKCS11Functions.h" +#include "../PCSC/Token.h" + +#include "CardTemplate.h" +#include "../Util/util.h" +#include "../Util/SyncroEvent.h" +#include +#include +#include "../LOGGER/Logger.h" + +using namespace CieIDLogger; + +extern CLog Log; + +extern std::mutex p11Mutex; +extern auto_reset_event p11slotEvent; +extern bool bP11Terminate; +extern bool bP11Initialized; + +extern uint8_t NXP_ATR[]; +extern uint8_t Gemalto_ATR[]; +extern uint8_t Gemalto2_ATR[]; +extern uint8_t STM_ATR[]; +extern uint8_t STM2_ATR[]; + +extern ByteArray baNXP_ATR; +extern ByteArray baGemalto_ATR; +extern ByteArray baGemalto2_ATR; +extern ByteArray baSTM_ATR; +extern ByteArray baSTM2_ATR; +extern ByteArray baSTM3_ATR; + +namespace p11 { + +DWORD CSlot::dwSlotCnt = 0; +SlotMap CSlot::g_mSlots; +std::thread CSlot::Thread; +CCardContext *CSlot::ThreadContext = NULL; +bool CSlot::bMonitorUpdate = false; + +CSlot::CSlot(const char *szReader) { + szName = szReader; + lastEvent = SE_NoEvent; + bUpdated = 0; + User = CKU_NOBODY; + dwP11ObjCnt = 0; + dwSessionCount = 0; + pTemplate = NULL; + //slotMutex.Create(mutexName(szReader)); + pSerialTemplate = NULL; + hCard = NULL; +} + +CSlot::~CSlot() { + Final(); +} + +CK_SLOT_ID CSlot::GetNewSlotID() { + init_func + return ++dwSlotCnt; +} + +static DWORD slotMonitor(SlotMap *pSlotMap) { + while (true) { + CCardContext Context; + CSlot::ThreadContext = &Context; + size_t dwSlotNum = pSlotMap->size(); + std::vector state(dwSlotNum); + std::vector> slot(dwSlotNum); + size_t i = 0; + DWORD ris; + { + std::unique_lock lock(p11Mutex); + for (SlotMap::const_iterator it = pSlotMap->begin(); it != pSlotMap->end(); it++, i++) { + if (!bP11Initialized) { + CSlot::ThreadContext = NULL; + return 0; + } + + state[i].szReader = it->second->szName.c_str(); + slot[i] = it->second; + if ((ris = SCardGetStatusChange(Context, 0, &state[i], 1)) != S_OK) { + if (ris != SCARD_E_TIMEOUT) { + LOG_ERROR("slotMonitor - SCardGetStatusChange error: %08X", ris); + // non uso la ExitThread!!! + // altrimenti non chiamo i distruttori, e mi rimane tutto appeso + // SOPRATTUTTO il p11Mutex + CSlot::ThreadContext = NULL; + return 1; + } + } + state[i].dwCurrentState = state[i].dwEventState & (~SCARD_STATE_CHANGED); + } + } + CSlot::bMonitorUpdate = false; + while (true) { + Context.validate(); + ris = SCardGetStatusChange(Context, 1000, state.data(), (DWORD)dwSlotNum); + if (ris != S_OK) { + if (CSlot::bMonitorUpdate || ris == SCARD_E_SYSTEM_CANCELLED || ris == SCARD_E_SERVICE_STOPPED || ris == SCARD_E_INVALID_HANDLE || ris == ERROR_INVALID_HANDLE) { + LOG_DEBUG("slotMonitor - Monitor Update"); + break; + } + if (ris == SCARD_E_CANCELLED || bP11Terminate || !bP11Initialized) { + LOG_DEBUG("slotMonitor - Terminate"); + p11slotEvent.set(); + CSlot::ThreadContext = NULL; + // no exitThread, vedi sopra; + return 0; + } + if (ris != SCARD_E_TIMEOUT && ris != SCARD_E_NO_READERS_AVAILABLE) { + LOG_ERROR("slotMonitor - SCardGetStatusChange error: %08X", ris); + p11slotEvent.set(); + CSlot::ThreadContext = NULL; + // no exitThread, vedi sopra; + return 1; + } + if (ris == SCARD_E_NO_READERS_AVAILABLE) { + LOG_INFO("slotMonitor - No smart card reader connected: %08X", ris); + CSlot::ThreadContext = NULL; + // no exitThread, vedi sopra; + return 1; + } + } + if (bP11Terminate || !bP11Initialized) { + LOG_INFO("slotMonitor - Terminate"); + p11slotEvent.set(); + CSlot::ThreadContext = NULL; + // no exitThread, vedi sopra; + return 0; + } + + for (size_t i = 0; i < dwSlotNum; i++) { + if ((state[i].dwCurrentState & SCARD_STATE_PRESENT) && + ((state[i].dwEventState & SCARD_STATE_EMPTY) || + (state[i].dwEventState & SCARD_STATE_UNAVAILABLE))) { + // una carta è stata estratta!! + // sincronizzo sul mutex principale p11 + // le funzioni attualmente in esecuzione che vanno sulla + // carta falliranno miseramente, ma se levi la carta + // mentre sto firmado mica è colpa mia! + + std::unique_lock lock(p11Mutex); + + slot[i]->lastEvent = SE_Removed; + slot[i]->Final(); + slot[i]->baATR.clear(); + p11slotEvent.set(); + } + if (((state[i].dwCurrentState & SCARD_STATE_UNAVAILABLE) || + (state[i].dwCurrentState & SCARD_STATE_EMPTY)) && + (state[i].dwEventState & SCARD_STATE_PRESENT)) { + // una carta è stata inserita!! + std::unique_lock lock(p11Mutex); + + slot[i]->lastEvent = SE_Inserted; + ByteArray ba; + slot[i]->GetATR(ba); + p11slotEvent.set(); + } + state[i].dwCurrentState = state[i].dwEventState & (~SCARD_STATE_CHANGED); + } + } + CSlot::ThreadContext = NULL; + } + // no exitThread, vedi sopra; + return 0; +} + +CK_SLOT_ID CSlot::AddSlot(std::shared_ptr pSlot) { + init_func + pSlot->hSlot = (CK_SLOT_ID)pSlot->GetNewSlotID(); + auto id = pSlot->hSlot; + g_mSlots.insert(std::make_pair(pSlot->hSlot, std::move(pSlot))); + return id; +} + +void CSlot::DeleteSlot(CK_SLOT_ID hSlotId) { + init_func + std::shared_ptr pSlot = GetSlotFromID(hSlotId); + + if (!pSlot) + throw p11_error(CKR_SLOT_ID_INVALID); + + pSlot->CloseAllSessions(); + +// try { +// g_mSlots.erase(hSlotId); +// } catch (...) { +// printf("erase error"); +// } + + pSlot->Final(); +} + +std::shared_ptr CSlot::GetSlotFromReaderName(const char *name) { + init_func + for (SlotMap::iterator it = g_mSlots.begin(); it != g_mSlots.end(); it++) { + if (strcmp(it->second->szName.c_str(), name) == 0) { + return it->second; + } + } + return nullptr; +} + +std::shared_ptr CSlot::GetSlotFromID(CK_SLOT_ID hSlotId) { + init_func + SlotMap::const_iterator pPair; + pPair = g_mSlots.find(hSlotId); + if (pPair == g_mSlots.end()) { + return nullptr; + } + return pPair->second; +} + +void CSlot::DeleteSlotList() { + init_func + +// int i = 0; + + if (Thread.joinable()) + Thread.join(); + + // TODO: verificare se è il caso di usare un thread con join a tempo + + /*while (i<5) { + if (Thread.join(1000)==OK) + break; + i=i+1; + if (CSlot::ThreadContext!=NULL) + SCardCancel(*CSlot::ThreadContext); + } + if (i==5) { + Thread.terminateThread(); + }*/ + + SlotMap::iterator it = CSlot::g_mSlots.begin(); + while (it != CSlot::g_mSlots.end()) { + DeleteSlot(it->second->hSlot); + it++;// = CSlot::g_mSlots.begin(); + } +} + +void CSlot::InitSlotList() { + // la InitSlotList deve aggiornare la liste degli slot; + // cioè, deve aggiungere gli slot che non c'erano prima e + // cancellare quelli che non ci sono più + init_func + bool bMapChanged = false; + DWORD readersLen = 0; + + CCardContext Context; + + if (!bP11Initialized) + return; + + auto ris = SCardListReaders(Context, NULL, NULL, &readersLen); + if (ris != S_OK) { + if (ris == SCARD_E_NO_READERS_AVAILABLE) + return; + throw windows_error(ris); + } + std::string readers; + readers.resize(readersLen + 1); + if ((ris = SCardListReaders(Context, NULL, &readers[0], &readersLen)) != SCARD_S_SUCCESS) + throw windows_error(ris); + + const char *szReaderName = readers.c_str(); + + while (*szReaderName != 0) { + if (!bP11Initialized) + return; + + // vediamo questo slot c'era già prima + LOG_INFO("InitSlotList - reader:%s", szReaderName); + std::shared_ptr pSlot = GetSlotFromReaderName(szReaderName); + if (pSlot == nullptr) { + auto pSlot = std::make_shared(szReaderName); + CK_SLOT_ID hSlotID = AddSlot(pSlot); + bMapChanged = true; + } + szReaderName = szReaderName + strnlen(szReaderName, readersLen) + 1; + } + // adesso vedo se tutti gli slot nella mappa ci sono ancora + for (SlotMap::iterator it = g_mSlots.begin(); it != g_mSlots.end(); it++) { + if (!bP11Initialized) + return; + + LOG_DEBUG("InitSlotList - %s", it->second->szName.c_str()); + const char *name = it->second->szName.c_str(); + + const char *szReaderName = readers.c_str(); + //char *szReaderName=szReaderAlloc; + bool bFound = false; + while (*szReaderName != 0) { + if (strcmp(name, szReaderName) == 0) { + bFound = true; + break; + } + szReaderName = szReaderName + strnlen(szReaderName, readersLen) + 1; + } + if (!bFound) { + CK_SLOT_ID ID = it->second->hSlot; + it--; + DeleteSlot(ID); + bMapChanged = true; + } + } + bMonitorUpdate = bMapChanged; + + if (!bP11Initialized) + return; + + if (!Thread.joinable()) + Thread = std::thread(slotMonitor, &g_mSlots); + +} + +bool CSlot::IsTokenPresent() { + init_func + SCARD_READERSTATE state; + memset(&state, 0, sizeof(SCARD_READERSTATE)); + state.szReader = szName.c_str(); + + Context.validate(); + bool retry = false; + while (true) { + DWORD ris = SCardGetStatusChange(Context, 0, &state, 1); + if (ris == S_OK) { + if ((state.dwEventState & SCARD_STATE_UNAVAILABLE) == SCARD_STATE_UNAVAILABLE) + throw p11_error(CKR_DEVICE_REMOVED); + if ((state.dwEventState & SCARD_STATE_PRESENT) == SCARD_STATE_PRESENT) + return true; + else + return false; + } else { + if (ris == SCARD_E_SERVICE_STOPPED || ris == SCARD_E_INVALID_HANDLE || ris == ERROR_INVALID_HANDLE) { + // devo prendere un nuovo context e riprovare + if (!retry) + retry = true; + else + throw windows_error(ris); + Context.renew(); + continue; + } + if (ris == SCARD_E_NO_READERS_AVAILABLE) + throw p11_error(CKR_DEVICE_REMOVED); + throw windows_error(ris); + } + } +} + +void CSlot::GetInfo(CK_SLOT_INFO_PTR pInfo) { + init_func + pInfo->flags = CKF_REMOVABLE_DEVICE | CKF_HW_SLOT; + // verifico che ci sia una carta inserita + + if (IsTokenPresent()) + pInfo->flags |= CKF_TOKEN_PRESENT; + + memset(pInfo->slotDescription, 0, 64); + size_t SDLen = min1(64, szName.size() - 1); + CryptoPP::memcpy_s(pInfo->slotDescription, 64, szName.c_str(), SDLen); + + memset(pInfo->manufacturerID, 0, 32); + // non so esattamente perchè, ma nella R1 il manufacturerID sono i primi 32 dello slotDescription + size_t MIDLen = min1(32, szName.size()); + CryptoPP::memcpy_s(pInfo->manufacturerID, 32, szName.c_str(), MIDLen); + + pInfo->hardwareVersion.major = 0; + pInfo->hardwareVersion.minor = 0; + + pInfo->firmwareVersion.major = 0; + pInfo->firmwareVersion.minor = 0; +} + +void CSlot::GetTokenInfo(CK_TOKEN_INFO_PTR pInfo) { + init_func + + if (pTemplate == nullptr) + pTemplate = CCardTemplate::GetTemplate(*this); + + if (pTemplate == nullptr) + throw p11_error(CKR_TOKEN_NOT_RECOGNIZED); + + memset(pInfo->label, 0, sizeof(pInfo->label)); + CryptoPP::memcpy_s((char*)pInfo->label, 32, pTemplate->szName.c_str(), min1(pTemplate->szName.length(), sizeof(pInfo->label))); + memset(pInfo->manufacturerID, ' ', sizeof(pInfo->manufacturerID)); + + std::string manifacturer; + size_t position; + if (baATR.indexOf(baNXP_ATR, position)) + manifacturer = "NXP"; + else if ((baATR.indexOf(baGemalto_ATR, position)) || + (baATR.indexOf(baGemalto2_ATR, position))) + manifacturer = "Gemalto"; + else if ((baATR.indexOf(baSTM_ATR, position))) + manifacturer = "STM"; + else if ((baATR.indexOf(baSTM2_ATR, position))) + manifacturer = "STM2"; + else if ((baATR.indexOf(baSTM3_ATR, position))) + manifacturer = "STM3"; + else + throw p11_error(CKR_TOKEN_NOT_RECOGNIZED); + + CryptoPP::memcpy_s((char*)pInfo->manufacturerID, 32, manifacturer.c_str(), manifacturer.size()); + + if (baSerial.isEmpty() || pSerialTemplate != pTemplate) { + pSerialTemplate = pTemplate; + baSerial = pTemplate->FunctionList.templateGetSerial(*this); + } + + std::string model; + pTemplate->FunctionList.templateGetModel(*this, model); + + memset(pInfo->serialNumber, 0, sizeof(pInfo->serialNumber)); + size_t UIDsize = min1(sizeof(pInfo->serialNumber), baSerial.size()); + CryptoPP::memcpy_s(pInfo->serialNumber, 16, baSerial.data(), UIDsize); + + CryptoPP::memcpy_s((char*)pInfo->label + pTemplate->szName.length() + 1, sizeof(pInfo->label) - pTemplate->szName.length() - 1, baSerial.data(), baSerial.size()); + + memset(pInfo->model, 0, sizeof(pInfo->model)); + CryptoPP::memcpy_s(pInfo->model, 16, model.c_str(), min1(model.length(), sizeof(pInfo->model))); + + CK_FLAGS dwFlags; + pTemplate->FunctionList.templateGetTokenFlags(*this, dwFlags); + pInfo->flags = dwFlags; + + pInfo->ulTotalPublicMemory = CK_UNAVAILABLE_INFORMATION; + pInfo->ulTotalPrivateMemory = CK_UNAVAILABLE_INFORMATION; + pInfo->ulFreePublicMemory = CK_UNAVAILABLE_INFORMATION; + pInfo->ulFreePrivateMemory = CK_UNAVAILABLE_INFORMATION; + pInfo->ulMaxSessionCount = MAXSESSIONS; + size_t dwSessCount = SessionCount(); + + pInfo->ulSessionCount = (CK_ULONG)dwSessCount; + size_t dwRWSessCount = RWSessionCount(); + + pInfo->ulRwSessionCount = dwRWSessCount; + pInfo->ulMaxRwSessionCount = MAXSESSIONS; + + pInfo->ulMinPinLen = 8; + pInfo->ulMaxPinLen = 8; + + pInfo->hardwareVersion.major = 0; + pInfo->hardwareVersion.minor = 0; + + pInfo->firmwareVersion.major = 0; + pInfo->firmwareVersion.minor = 0; + + CryptoPP::memcpy_s((char*)pInfo->utcTime, 16, "1234567890123456", 16); // OK +} + +void CSlot::CloseAllSessions() { + init_func + + SessionMap::iterator it = CSession::g_mSessions.begin(); + while (it != CSession::g_mSessions.end()) { + if (it->second->pSlot.get() == this) { + CSession *pSession = it->second.get(); + it++; + CSession::DeleteSession(pSession->hSessionHandle); + } else it++; + } +} + +void CSlot::Init() { + init_func + if (!bUpdated) { + + if (pTemplate == nullptr) + pTemplate = CCardTemplate::GetTemplate(*this); + + + if (pTemplate == nullptr) + throw p11_error(CKR_TOKEN_NOT_RECOGNIZED); + + pTemplate->FunctionList.templateInitCard(pTemplateData, *this); + bUpdated = true; + } +} + +void CSlot::Final() { + if (bUpdated) { + // cancello i dati del template + pTemplate->FunctionList.templateFinalCard(pTemplateData); + pTemplate = NULL; + + baATR.clear(); + baSerial.clear(); + + P11Objects.clear(); + + // cancello tutte le sessioni + SessionMap::iterator it = CSession::g_mSessions.begin(); + while (it != CSession::g_mSessions.end()) { + if (it->second->pSlot.get() == this) { + it = CSession::g_mSessions.erase(it); + dwSessionCount--; + } else it++; + } + // dwSessionCount dovrebbe essere già a 0... + // ma per sicurezza lo setto a manina + + User = CKU_NOBODY; + dwSessionCount = 0; + bUpdated = false; + } +} + +std::shared_ptr CSlot::FindP11Object(CK_OBJECT_CLASS objClass, CK_ATTRIBUTE_TYPE attr, CK_BYTE *val, int valLen) { + init_func + for (DWORD i = 0; i < P11Objects.size(); i++) { + auto obj = P11Objects[i]; + if (obj->ObjClass == objClass) { + ByteArray *attrVal = obj->getAttribute(attr); + if (attrVal && attrVal->size() == valLen) { + if (memcmp(attrVal->data(), val, valLen) == 0) { + return obj; + } + } + } + } + return nullptr; +} + +void CSlot::AddP11Object(std::shared_ptr p11obj) { + init_func + p11obj->pSlot = this; + P11Objects.emplace_back(std::move(p11obj)); +} + +void CSlot::ClearP11Objects() { + init_func + P11Objects.clear(); + ObjP11Map.clear(); + HandleP11Map.clear(); +} + +void CSlot::DelP11Object(const std::shared_ptr& object) { + init_func + bool bFound = false; + for (P11ObjectVector::iterator it = P11Objects.begin(); it != P11Objects.end(); it++) { + if (*it == object) { + bFound = true; + P11Objects.erase(it); + break; + } + } + ER_ASSERT(bFound, ERR_FIND_OBJECT) + + ObjHandleMap::iterator itObj = ObjP11Map.find(object); + if (itObj != ObjP11Map.end()) { + HandleObjMap::iterator itHandle = HandleP11Map.find(itObj->second); + ObjP11Map.erase(itObj); + if (itHandle != HandleP11Map.end()) + HandleP11Map.erase(itHandle); + } +} + +size_t CSlot::SessionCount() { + init_func + return dwSessionCount; +} + +size_t CSlot::RWSessionCount() { + init_func + size_t dwRWSessCount = 0; + for (SessionMap::iterator it = CSession::g_mSessions.begin(); it != CSession::g_mSessions.end(); it++) { + if (it->second->pSlot.get() == this && (it->second->flags & CKF_RW_SESSION) != 0) + dwRWSessCount++; + } + return dwRWSessCount; +} + +CK_OBJECT_HANDLE CSlot::GetIDFromObject(const std::shared_ptr&pObject) { + init_func + + if (pObject->IsPrivate() && User != CKU_USER) + throw p11_error(CKR_USER_NOT_LOGGED_IN); + + ObjHandleMap::const_iterator pPair; + pPair = ObjP11Map.find(pObject); + if (pPair == ObjP11Map.end()) { + // non ho trovato l'oggetto nella mappa degli oggetti; + // devo aggiungerlo + + CK_OBJECT_HANDLE hObject = (CK_OBJECT_HANDLE)&pObject;//GetNewObjectID(); + ObjP11Map[pObject] = hObject; + HandleP11Map[hObject] = pObject; + return hObject; + } + return pPair->second; +} + +// CK_OBJECT_HANDLE CSlot::GetNewObjectID() { +// init_func +// return InterlockedIncrement(&dwP11ObjCnt); +// } + +void CSlot::DelObjectHandle(const std::shared_ptr& pObject) { + init_func + ObjHandleMap::iterator pPair; + pPair = ObjP11Map.find(pObject); + if (pPair != ObjP11Map.end()) { + HandleObjMap::iterator pPair2; + pPair2 = HandleP11Map.find(pPair->second); + if (pPair2 != HandleP11Map.end()) + HandleP11Map.erase(pPair2); + ObjP11Map.erase(pPair); + } +} + +std::shared_ptr CSlot::GetObjectFromID(CK_OBJECT_HANDLE hObjectHandle) { + init_func + HandleObjMap::const_iterator pPair; + pPair = HandleP11Map.find(hObjectHandle); + if (pPair == HandleP11Map.end()) + return nullptr; + + return pPair->second; +} + +void CSlot::Connect() { + init_func + DWORD dwProtocol; + + Context.validate(); + bool retry = false; + while (true) { + DWORD ris = SCardConnect(Context, szName.c_str(), SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, &hCard, &dwProtocol); + if (ris == SCARD_S_SUCCESS) { + return; + } else { + if (ris == SCARD_E_SERVICE_STOPPED || ris == SCARD_E_INVALID_HANDLE || ris == ERROR_INVALID_HANDLE) { + if (!retry) + retry = true; + else { + throw windows_error(ris); + } + Context.renew(); + } else { + if (ris != SCARD_S_SUCCESS) + throw windows_error(ris); + } + } + } +} + +#define SCARD_ATTR_VALUE(Class, Tag) ((((uint32_t)(Class)) << 16) | ((uint32_t)(Tag))) +#define SCARD_CLASS_ICC_STATE 9 /**< ICC State specific definitions */ +#define SCARD_ATTR_ATR_STRING SCARD_ATTR_VALUE(SCARD_CLASS_ICC_STATE, 0x0303) /**< Answer to reset (ATR) string. */ + + +ByteDynArray CSlot::GetATR() { + init_func + + DWORD atrLen = 40; + char ATR[40]; + long ret = SCardGetAttrib(this->hCard, SCARD_ATTR_ATR_STRING, (uint8_t*)ATR, &atrLen); + if(ret == SCARD_S_SUCCESS) { + LOG_INFO("CSlot::GetATR() - ATR:"); + LOG_BUFFER((BYTE*)ATR, atrLen); + return ByteArray((BYTE*)ATR, atrLen); + } else { + LOG_INFO("CSlot::GetATR() - no card inserted"); + return ByteArray(); + } +//readCIEType +// SCARD_READERSTATE state; +// state.szReader = this->szName.data(); +// long ret = SCardGetStatusChange(CSlot::Context, 0, &state, 1); +// +// printf("\nSCardGetStatusChange: %x\n", ret); +// +// if (state.cbAtr > 0) { +// Log.write("ATR Letto:"); +// if(state.cbAtr > 32) +// state.cbAtr = 32; +// +// Log.writeBinData(state.rgbAtr, state.cbAtr); +// return ByteArray(state.rgbAtr, state.cbAtr); +// } +// else { +// Log.write("ATR Letto: -nessuna carta inserita-"); +// return ByteArray(); +// } +} + +void CSlot::GetATR(ByteArray &ATR) { + init_func + if (baATR.size() != 0) { + ATR = baATR; + return; + } + baATR = GetATR(); + ATR = baATR; +} + +} diff --git a/libcie-pkcs11/PKCS11/initP11.cpp b/libcie-pkcs11/PKCS11/initP11.cpp index a6563272..ec4c2155 100644 --- a/libcie-pkcs11/PKCS11/initP11.cpp +++ b/libcie-pkcs11/PKCS11/initP11.cpp @@ -1,10 +1,10 @@ - -#include "InitP11.h" - -namespace p11 { - -void InitP11(const char *p11Path) { - // per usi futuri -} - -} + +#include "InitP11.h" + +namespace p11 { + +void InitP11(const char *p11Path) { + // per usi futuri +} + +} diff --git a/libcie-pkcs11/PKCS11/session.cpp b/libcie-pkcs11/PKCS11/session.cpp index 087edd30..484f581f 100644 --- a/libcie-pkcs11/PKCS11/session.cpp +++ b/libcie-pkcs11/PKCS11/session.cpp @@ -1,1401 +1,1402 @@ -//#include "../StdAfx.h" -#include "session.h" -#include "CardTemplate.h" -#include "../Util/util.h" -#include "../Crypto/RSA.h" -#include "../Util/TLV.h" - -extern CLog Log; - -namespace { -template -class resetter; - -template -resetter make_resetter(T&) noexcept; - -template -class resetter> { - private: - std::unique_ptr * m_p; - - friend resetter> make_resetter>(std::unique_ptr& p) noexcept; - resetter(std::unique_ptr& p) noexcept : m_p(&p) {} - - void reset() noexcept(noexcept(m_p->reset())) { - if (m_p) - m_p->reset(); - - m_p = nullptr; - } - - public: - resetter(const resetter&) = delete; - resetter(resetter&& other) noexcept : m_p(std::exchange(other.m_p, nullptr)) {} - - resetter& operator=(const resetter&) = delete; - - resetter& operator=(resetter&& other) noexcept(noexcept(reset())) { - reset(); - m_p = std::exchange(other.m_p, nullptr); - return *this; - } - - ~resetter() { //noexcept(noexcept(reset())) - reset(); - } - - void release() noexcept { - m_p = nullptr; - } -}; - -template -resetter make_resetter(T& p) noexcept { - return resetter(p); -} - -} - -namespace p11 { - -DWORD CSession::dwSessionCnt = 0; -SessionMap CSession::g_mSessions; - -CSession::CSession() { - pSlot = NULL; - bFindInit = false; -} - - -CK_SLOT_ID CSession::GetNewSessionID() { - init_func - dwSessionCnt++; - __sync_fetch_and_add(&dwSessionCnt, 1); - return dwSessionCnt; -} - -CK_SESSION_HANDLE CSession::AddSession(std::unique_ptr pSession) { - init_func - pSession->hSessionHandle = GetNewSessionID(); - auto id = pSession->hSessionHandle; - - pSession->pSlot->pTemplate->FunctionList.templateInitSession(pSession->pSlot->pTemplateData); - - pSession->pSlot->dwSessionCount++; - g_mSessions.insert(std::make_pair(pSession->hSessionHandle, std::move(pSession))); - - return id; -} - -void CSession::DeleteSession(CK_SESSION_HANDLE hSessionHandle) { - init_func - std::shared_ptr pSession=GetSessionFromID(hSessionHandle); - - ER_ASSERT(pSession != nullptr, ERR_SESSION_NOT_OPENED); - - pSession->pSlot->dwSessionCount--; - if (pSession->pSlot->dwSessionCount == 0) { - if (pSession->pSlot->User != CKU_NOBODY) { - pSession->Logout(); - } - } - - pSession->pSlot->pTemplate->FunctionList.templateFinalSession(pSession->pSlot->pTemplateData); - g_mSessions.erase(hSessionHandle); -} - -std::shared_ptr CSession::GetSessionFromID(CK_SESSION_HANDLE hSessionHandle) { - init_func - SessionMap::const_iterator pPair; - pPair = g_mSessions.find(hSessionHandle); - if (pPair == g_mSessions.end()) - return nullptr; - - return pPair->second; -} - -/* ******************* */ -/* LOGIN e LOGOUT */ -/* ******************* */ - -void CSession::Login(CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG ulPinLen) { - init_func - - if (pSlot->User == CKU_USER && userType == CKU_SO) - throw p11_error(CKR_USER_ANOTHER_ALREADY_LOGGED_IN); - if (pSlot->User == CKU_SO && userType == CKU_USER) - throw p11_error(CKR_USER_ANOTHER_ALREADY_LOGGED_IN); - if (userType == CKU_SO) { - if (ExistsRO()) - throw p11_error(CKR_SESSION_READ_ONLY_EXISTS); - } - if (pSlot->User != CKU_NOBODY) - throw p11_error(CKR_USER_ALREADY_LOGGED_IN); - - ByteArray baPin(pPin, ulPinLen); - pSlot->pTemplate->FunctionList.templateLogin(pSlot->pTemplateData, userType, baPin); - - pSlot->User = userType; -} - -void CSession::Logout() { - init_func - - pSlot->pTemplate->FunctionList.templateLogout(pSlot->pTemplateData, pSlot->User); - - for (auto obj = pSlot->P11Objects.begin(); obj != pSlot->P11Objects.end(); obj++) { - if ((*obj)->IsPrivate()) - pSlot->DelObjectHandle(*obj); - } - pSlot->User = CKU_NOBODY; -} - -/* ******************* */ -/* Find Objects */ -/* ******************* */ - -void CSession::FindObjectsInit(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { - init_func - if (bFindInit) - throw p11_error(CKR_OPERATION_ACTIVE); - findResult.clear(); - if (ulCount == 0) { - for (auto obj = pSlot->P11Objects.begin(); obj != pSlot->P11Objects.end(); obj++) { - try { - findResult.push_back(pSlot->GetIDFromObject(*obj)); - } catch (p11_error &err) { - if (err.getP11ErrorCode() != CKR_USER_NOT_LOGGED_IN) - throw; - } - } - } else { - for (auto obj = pSlot->P11Objects.begin(); obj != pSlot->P11Objects.end(); obj++) { - bool bSkip = false; - - for (unsigned int j = 0; j < ulCount && !bSkip; j++) { - try { - ByteArray* attr = (*obj)->getAttribute(pTemplate[j].type); - if (attr==nullptr) - bSkip = true; - else { - if (attr->size() != pTemplate[j].ulValueLen) - bSkip = true; - else if ((*attr) != ByteArray((BYTE*)pTemplate[j].pValue, pTemplate[j].ulValueLen)) - bSkip = true; - } - } catch (p11_error &err) { - if (err.getP11ErrorCode() != CKR_USER_NOT_LOGGED_IN) - throw; - bSkip = true; - } - } - if (!bSkip) { - try { - findResult.push_back(pSlot->GetIDFromObject(*obj)); - } catch (p11_error &err) { - if (err.getP11ErrorCode() != CKR_USER_NOT_LOGGED_IN) - throw; - } - /*if (Log.LogParam) { - ByteArray *Label = NULL; - pSlot->P11Objects[i]->getAttribute(CKA_LABEL, Label); - Log.writePure("Object found %i:", i); - Log.writePure("Class: %x", pSlot->P11Objects[i]->ObjClass); - if (Label) { - Log.writePure("Label:"); - info.logParameter(Label->data(), Label->size()); - } - }*/ - } - } - } - bFindInit = true; -} - -void CSession::FindObjects(CK_OBJECT_HANDLE_PTR phObject, CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount) { - init_func - if (!bFindInit) - throw p11_error(CKR_OPERATION_NOT_INITIALIZED); - *pulObjectCount = 0; - int iCnt = 0; - while (!findResult.empty() && ulMaxObjectCount>0) { - phObject[iCnt] = findResult.back(); - findResult.pop_back(); - iCnt++; - ulMaxObjectCount--; - } - *pulObjectCount = iCnt; -} - -void CSession::FindObjectsFinal() { - init_func - if (!bFindInit) - throw p11_error(CKR_OPERATION_NOT_INITIALIZED); - findResult.clear(); - bFindInit = false; -} - -CK_RV CSession::GetAttributeValue(CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { - init_func - - std::shared_ptr pObject = pSlot->GetObjectFromID(hObject); - if (pObject == nullptr) - throw p11_error(CKR_OBJECT_HANDLE_INVALID); - - return pObject->GetAttributeValue(pTemplate, ulCount); -} - -ByteDynArray GetTemplateValue(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_ATTRIBUTE_TYPE type) { - init_func - for (unsigned int i = 0; iUser != CKU_USER) - throw p11_error(CKR_USER_NOT_LOGGED_IN); - - std::shared_ptr pObject = pSlot->pTemplate->FunctionList.templateCreateObject(pSlot->pTemplateData, pTemplate, ulCount); - - if (pObject != nullptr) - return pSlot->GetIDFromObject(pObject); - else - throw p11_error(CKR_GENERAL_ERROR); - -} - -CK_OBJECT_HANDLE CSession::GenerateKey(CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { - init_func - - // NON SUPPORTATO DALLA CIE - throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); - - /*if ((flags & CKF_RW_SESSION) == 0) - throw p11_error(CKR_SESSION_READ_ONLY); - - if (pSlot->User != CKU_USER) - throw p11_error(CKR_USER_NOT_LOGGED_IN); - - std::shared_ptr pKey = pSlot->pTemplate->FunctionList.templateGenerateKey(pSlot->pTemplateData, pMechanism, pTemplate, ulCount); - - if (pKey != nullptr) { - return pSlot->GetIDFromObject(pKey); - } - else - throw p11_error(CKR_GENERAL_ERROR);*/ -} - -void CSession::GenerateKeyPair(CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey) { - init_func - - // NON SUPPORTATO DALLA CIE - throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); - - /* if ((flags & CKF_RW_SESSION) == 0) - throw p11_error(CKR_SESSION_READ_ONLY); - - if (pSlot->User != CKU_USER) - throw p11_error(CKR_USER_NOT_LOGGED_IN); - - std::shared_ptr pPublicKey = nullptr; - std::shared_ptr pPrivateKey = nullptr; - pSlot->pTemplate->FunctionList.templateGenerateKeyPair(pSlot->pTemplateData, pMechanism, pPublicKeyTemplate, ulPublicKeyAttributeCount, pPrivateKeyTemplate, ulPrivateKeyAttributeCount, pPublicKey, pPrivateKey); - - if (pPublicKey != nullptr) { - *phPublicKey = pSlot->GetIDFromObject(pPublicKey); - } - else - throw p11_error(CKR_GENERAL_ERROR); - - if (pPrivateKey != nullptr) { - *phPrivateKey = pSlot->GetIDFromObject(pPrivateKey); - } - else - throw p11_error(CKR_GENERAL_ERROR); - */ -} - -void CSession::DestroyObject(CK_OBJECT_HANDLE hObject) { - init_func - - if ((flags & CKF_RW_SESSION) == 0) - throw p11_error(CKR_SESSION_READ_ONLY); - - if (pSlot->User != CKU_USER) - throw p11_error(CKR_USER_NOT_LOGGED_IN); - - std::shared_ptr pObject = pSlot->GetObjectFromID(hObject); - if (pObject == nullptr) - throw p11_error(CKR_OBJECT_HANDLE_INVALID); - - pSlot->pTemplate->FunctionList.templateDestroyObject(pSlot->pTemplateData, *pObject); - pSlot->DelP11Object(pObject); -} - -bool CSession::ExistsRO() { - init_func - for (SessionMap::const_iterator it = g_mSessions.begin(); it != g_mSessions.end(); it++) { - if (it->second->pSlot == pSlot && (it->second->flags & CKF_RW_SESSION) == 0) { - return true; - } - } - - return false; -} - -bool CSession::ExistsSO_RW() { - init_func - if (pSlot->User != CKU_SO) - return false; - for (SessionMap::const_iterator it = g_mSessions.begin(); it != g_mSessions.end(); it++) { - if (it->second->pSlot == pSlot && (it->second->flags & CKF_RW_SESSION) != 0) - return true; - } - - return false; -} - -/* ******************* */ -/* Digest */ -/* ******************* */ - -void CSession::DigestInit(CK_MECHANISM_PTR pMechanism) { - init_func - if (pDigestMechanism != nullptr) - throw p11_error(CKR_OPERATION_ACTIVE); - - switch (pMechanism->mechanism) { - case CKM_SHA_1: { - auto mech = std::unique_ptr(new CDigestSHA(shared_from_this())); - mech->DigestInit(); - - pDigestMechanism = std::move(mech); - break; - } - case CKM_SHA256: { - auto mech = std::unique_ptr(new CDigestSHA256(shared_from_this())); - mech->DigestInit(); - - pDigestMechanism = std::move(mech); - break; - } - case CKM_MD5: { - auto mech = std::unique_ptr(new CDigestMD5(shared_from_this())); - mech->DigestInit(); - - pDigestMechanism = std::move(mech); - break; - } - default: - throw p11_error(CKR_MECHANISM_INVALID); - } -} - -void CSession::Digest(ByteArray &Data, ByteArray &Digest) { - init_func - - CK_ULONG ulReqLen = pDigestMechanism->DigestLength(); - - if (!Digest.isNull() && Digest.size() < ulReqLen) - throw p11_error(CKR_BUFFER_TOO_SMALL); - - Digest = Digest.left(ulReqLen); - if (Digest.isNull()) - return; - - DigestUpdate(Data); - DigestFinal(Digest); - -} - -void CSession::DigestUpdate(ByteArray &Data) { - init_func - if (pDigestMechanism==nullptr) - throw p11_error(CKR_OPERATION_NOT_INITIALIZED); - - pDigestMechanism->DigestUpdate(Data); -} - -void CSession::DigestFinal(ByteArray &Digest) { - init_func - if (pDigestMechanism == nullptr) - throw p11_error(CKR_OPERATION_NOT_INITIALIZED); - - auto mech = std::move(pDigestMechanism); - CK_ULONG ulReqLen = mech->DigestLength(); - - if (!Digest.isNull() && Digest.size()DigestFinal(Digest); - -} - -/* ******************* */ -/* Verify */ -/* ******************* */ - -void CSession::VerifyInit(CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { - init_func - if (pVerifyMechanism != nullptr) - throw p11_error(CKR_OPERATION_ACTIVE); - - std::shared_ptr pObject = pSlot->GetObjectFromID(hKey); - if (pObject == nullptr) - throw p11_error(CKR_KEY_HANDLE_INVALID); - if (pObject->ObjClass != CKO_PUBLIC_KEY) - throw p11_error(CKR_KEY_HANDLE_INVALID); - auto pVerifyKey = std::static_pointer_cast(pObject); - - - if (pVerifyKey->IsPrivate() && pSlot->User != CKU_USER) - throw p11_error(CKR_USER_NOT_LOGGED_IN); - - ByteArray *baAttrVal = pVerifyKey->getAttribute(CKA_VERIFY); - if (baAttrVal==nullptr) - throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); - else { - if (ByteArrayToVar(*baAttrVal, CK_BBOOL) == FALSE) - throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); - } - - switch (pMechanism->mechanism) { - case CKM_SHA1_RSA_PKCS: { - auto mech = std::unique_ptr(new CRSAwithSHA1(shared_from_this())); - mech->VerifyInit(hKey); - pVerifyMechanism = std::move(mech); - break; - } - case CKM_SHA256_RSA_PKCS: { - auto mech = std::unique_ptr(new CRSAwithSHA256(shared_from_this())); - mech->VerifyInit(hKey); - pVerifyMechanism = std::move(mech); - break; - } - case CKM_MD5_RSA_PKCS: { - auto mech = std::unique_ptr(new CRSAwithMD5(shared_from_this())); - mech->VerifyInit(hKey); - pVerifyMechanism = std::move(mech); - break; - } - case CKM_RSA_PKCS: { - auto mech = std::unique_ptr(new CRSA_PKCS1(shared_from_this())); - mech->VerifyInit(hKey); - pVerifyMechanism = std::move(mech); - break; - } - /* NON SUPPORTATO DALLA CIE - case CKM_RSA_X_509: - { - auto mech = std::unique_ptr(new CRSA_X509(shared_from_this())); - mech->VerifyInit(hKey); - pVerifyMechanism = std::move(mech); - break; - }*/ - default: - throw p11_error(CKR_MECHANISM_INVALID); - } -} - -void CSession::Verify(ByteArray &Data, ByteArray &Signature) { - init_func - - if (pVerifyMechanism == nullptr) - throw p11_error(CKR_OPERATION_NOT_INITIALIZED); - - VerifyUpdate(Data); - VerifyFinal(Signature); -} - -void CSession::VerifyUpdate(ByteArray &Data) { - init_func - if (pVerifyMechanism == nullptr) - throw p11_error(CKR_OPERATION_NOT_INITIALIZED); - - pVerifyMechanism->VerifyUpdate(Data); -} - -void CSession::VerifyFinal(ByteArray &Signature) { - init_func - if (pVerifyMechanism == nullptr) - throw p11_error(CKR_OPERATION_NOT_INITIALIZED); - - auto mech = make_resetter(pVerifyMechanism); - pVerifyMechanism->VerifyFinal(Signature); -} - -/* ******************** */ -/* VerifyRecover */ -/* ******************** */ - -void CSession::VerifyRecoverInit(CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { - init_func - if (pVerifyRecoverMechanism!= nullptr) - throw p11_error(CKR_OPERATION_ACTIVE); - - std::shared_ptr pObject = pSlot->GetObjectFromID(hKey); - if (pObject == NULL) - throw p11_error(CKR_KEY_HANDLE_INVALID); - if (pObject->ObjClass != CKO_PUBLIC_KEY) - throw p11_error(CKR_KEY_HANDLE_INVALID); - auto pVerifyRecoverKey = std::static_pointer_cast(pObject); - - - if (pVerifyRecoverKey->IsPrivate() && pSlot->User != CKU_USER) - throw p11_error(CKR_USER_NOT_LOGGED_IN); - - ByteArray *baAttrVal = pVerifyRecoverKey->getAttribute(CKA_VERIFY_RECOVER); - if (baAttrVal==nullptr) - throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); - else { - if (ByteArrayToVar(*baAttrVal, CK_BBOOL) == FALSE) - throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); - } - - switch (pMechanism->mechanism) { - case CKM_RSA_PKCS: { - auto mech = std::unique_ptr(new CRSA_PKCS1(shared_from_this())); - mech->VerifyRecoverInit(hKey); - pVerifyRecoverMechanism = std::move(mech); - break; - } - /* NON SUPPORTATO DALLA CIE - case CKM_RSA_X_509: - { - auto mech = std::unique_ptr(new CRSA_X509(shared_from_this())); - mech->VerifyRecoverInit(hKey); - pVerifyRecoverMechanism = std::move(mech); - break; - }*/ - default: - throw p11_error(CKR_MECHANISM_INVALID); - } -} - -void CSession::VerifyRecover(ByteArray &Signature, ByteArray &Data) { - init_func - if (pVerifyRecoverMechanism == nullptr) - throw p11_error(CKR_OPERATION_NOT_INITIALIZED); - - auto mech = std::move(pVerifyRecoverMechanism); - - CK_ULONG ulKeyLen = pVerifyRecoverMechanism->VerifyRecoverLength(); - ByteDynArray baData = pVerifyRecoverMechanism->VerifyRecover(Signature); - - if (!Data.isNull() && Data.size() pObject = pSlot->GetObjectFromID(hKey); - if (pObject == nullptr) - throw p11_error(CKR_KEY_HANDLE_INVALID); - if (pObject->ObjClass != CKO_PRIVATE_KEY) - throw p11_error(CKR_KEY_HANDLE_INVALID); - auto pSignKey = std::static_pointer_cast(pObject); - - - if (pSignKey->IsPrivate() && pSlot->User != CKU_USER) - throw p11_error(CKR_USER_NOT_LOGGED_IN); - - ByteArray *baAttrVal = pSignKey->getAttribute(CKA_SIGN); - if (baAttrVal==nullptr) - throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); - else { - if (ByteArrayToVar(*baAttrVal, CK_BBOOL) == FALSE) - throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); - } - - switch (pMechanism->mechanism) { - case CKM_SHA1_RSA_PKCS: { - auto mech = std::unique_ptr(new CRSAwithSHA1(shared_from_this())); - mech->SignInit(hKey); - pSignMechanism = std::move(mech); - break; - } - case CKM_SHA256_RSA_PKCS: { - auto mech = std::unique_ptr(new CRSAwithSHA256(shared_from_this())); - mech->SignInit(hKey); - pSignMechanism = std::move(mech); - break; - } - case CKM_MD5_RSA_PKCS: { - auto mech = std::unique_ptr(new CRSAwithMD5(shared_from_this())); - mech->SignInit(hKey); - pSignMechanism = std::move(mech); - break; - } - case CKM_RSA_PKCS: { - auto mech = std::unique_ptr(new CRSA_PKCS1(shared_from_this())); - mech->SignInit(hKey); - pSignMechanism = std::move(mech); - break; - } - /* NON SUPPORTATO DALLA CIE - case CKM_RSA_X_509: - { - auto mech = std::unique_ptr(new CRSA_X509(shared_from_this())); - mech->SignInit(hKey); - pSignMechanism = std::move(mech); - break; - }*/ - default: - throw p11_error(CKR_MECHANISM_INVALID); - } -} - -void CSession::Sign(ByteArray &Data, ByteArray &Signature) { - init_func - if (pSignMechanism == nullptr) - throw p11_error(CKR_OPERATION_NOT_INITIALIZED); - - pSignMechanism->SignReset(); - SignUpdate(Data); - SignFinal(Signature); -} - -void CSession::SignUpdate(ByteArray &Data) { - init_func - if (pSignMechanism == nullptr) - throw p11_error(CKR_OPERATION_NOT_INITIALIZED); - - pSignMechanism->SignUpdate(Data); -} - -void CSession::SignFinal(ByteArray &Signature) { - init_func - if (pSignMechanism == nullptr) - throw p11_error(CKR_OPERATION_NOT_INITIALIZED); - - auto mech = make_resetter(pSignMechanism); - - std::shared_ptr pObject = pSlot->GetObjectFromID(pSignMechanism->hSignKey); - if (pObject == NULL) - throw p11_error(CKR_KEY_HANDLE_INVALID); - if (pObject->ObjClass != CKO_PRIVATE_KEY) - throw p11_error(CKR_KEY_HANDLE_INVALID); - - auto pSignKey = std::static_pointer_cast(pObject); - - if (pSignKey->IsPrivate() && pSlot->User != CKU_USER) - throw p11_error(CKR_USER_NOT_LOGGED_IN); - - if (Signature.isNull()) { - CK_ULONG ulSignLength = pSignMechanism->SignLength(); - Signature = ByteArray(nullptr, ulSignLength); - mech.release(); - return; - } - - ByteDynArray baSignBuffer = pSignMechanism->SignFinal(); - - bool bSilent = false; - ByteDynArray baSignature; - pSlot->pTemplate->FunctionList.templateSign(pSlot->pTemplateData, pSignKey.get(), baSignBuffer, baSignature, pSignMechanism->mtType, bSilent); - - if (Signature.size() pObject = pSlot->GetObjectFromID(hKey); - if (pObject == NULL) - throw p11_error(CKR_KEY_HANDLE_INVALID); - if (pObject->ObjClass != CKO_PRIVATE_KEY) - throw p11_error(CKR_KEY_HANDLE_INVALID); - auto pSignRecoverKey = std::static_pointer_cast(pObject); - - - if (pSignRecoverKey->IsPrivate() && pSlot->User != CKU_USER) - throw p11_error(CKR_USER_NOT_LOGGED_IN); - - ByteArray *baAttrVal = pSignRecoverKey->getAttribute(CKA_SIGN_RECOVER); - if (baAttrVal == nullptr) - throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); - else { - if (ByteArrayToVar(*baAttrVal, CK_BBOOL) == FALSE) - throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); - } - - switch (pMechanism->mechanism) { - case CKM_RSA_PKCS: { - auto mech = std::unique_ptr(new CRSA_PKCS1(shared_from_this())); - mech->SignRecoverInit(hKey); - pSignRecoverMechanism = std::move(mech); - break; - } - /* - NON SUPPORTATO DALLA CIE - case CKM_RSA_X_509: - { - auto mech = std::unique_ptr(new CRSA_X509(shared_from_this())); - mech->SignRecoverInit(hKey); - pSignRecoverMechanism = std::move(mech); - break; - }*/ - default: - throw p11_error(CKR_MECHANISM_INVALID); - } -} - -void CSession::SignRecover(ByteArray &Data, ByteArray &Signature) { - init_func - if (pSignRecoverMechanism == nullptr) - throw p11_error(CKR_OPERATION_NOT_INITIALIZED); - - auto mech = make_resetter(pSignRecoverMechanism); - - std::shared_ptr pObject = pSlot->GetObjectFromID(pSignRecoverMechanism->hSignRecoverKey); - if (pObject == nullptr) - throw p11_error(CKR_KEY_HANDLE_INVALID); - if (pObject->ObjClass != CKO_PRIVATE_KEY) - throw p11_error(CKR_KEY_HANDLE_INVALID); - auto pSignRecoverKey = std::static_pointer_cast(pObject); - - - if (pSignRecoverKey->IsPrivate() && pSlot->User != CKU_USER) - throw p11_error(CKR_USER_NOT_LOGGED_IN); - - if (Signature.isNull()) { - CK_ULONG ulSignRecoverLength = pSignRecoverMechanism->SignRecoverLength(); - Signature = ByteArray(nullptr, ulSignRecoverLength); - mech.release(); - return; - } - - ByteDynArray baSignRecoverBuffer; - pSignRecoverMechanism->SignRecover(Data); - - bool bSilent = false; - - ByteDynArray baSignature; - pSlot->pTemplate->FunctionList.templateSignRecover(pSlot->pTemplateData, pSignRecoverKey.get(), baSignRecoverBuffer, baSignature, pSignRecoverMechanism->mtType, bSilent); - - if (Signature.size() pObject = pSlot->GetObjectFromID(hKey); -//if (pObject == NULL) -// throw p11_error(CKR_KEY_HANDLE_INVALID); -//if (pObject->ObjClass != CKO_PUBLIC_KEY) -// throw p11_error(CKR_KEY_HANDLE_INVALID); -//auto pEncryptKey = std::static_pointer_cast(pObject); - -//if (pEncryptKey->IsPrivate() && pSlot->User != CKU_USER) -// throw p11_error(CKR_USER_NOT_LOGGED_IN); - -//ByteArray *baAttrVal = pEncryptKey->getAttribute(CKA_ENCRYPT); -//if (baAttrVal == nullptr) -// throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); -//else { -// if (ByteArrayToVar(*baAttrVal, CK_BBOOL) == FALSE) -// throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); -//} - -//switch (pMechanism->mechanism) { -//case CKM_RSA_PKCS: -//{ -// auto mech = std::unique_ptr(new CRSA_PKCS1(shared_from_this())); -// mech->EncryptInit(hKey); -// pEncryptMechanism = std::move(mech); -// break; -//} -///* NON SUPPORTATO DALLA CIE -//case CKM_RSA_X_509: -//{ -// auto mech = std::unique_ptr(new CRSA_X509(shared_from_this())); -// mech->EncryptInit(hKey); -// pEncryptMechanism = std::move(mech); -// break; -//}*/ -//default: -// throw p11_error(CKR_MECHANISM_INVALID); -//} -//} - -//void CSession::Encrypt(ByteArray &Data, ByteArray &EncryptedData) -//{ -// init_func - -// // NON SUPPORTATO DALLA CIE -// throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); - -/*if (pEncryptMechanism == nullptr) - throw p11_error(CKR_OPERATION_NOT_INITIALIZED); - -CK_ULONG ulReqLen = pEncryptMechanism->EncryptLength(); - -if (!EncryptedData.isNull() && EncryptedData.size() < ulReqLen) - throw p11_error(CKR_BUFFER_TOO_SMALL); - -EncryptedData = EncryptedData.left(ulReqLen); -if (EncryptedData.isNull()) - return; - -EncryptUpdate(Data, EncryptedData); - -EncryptFinal(EncryptedData);*/ -/*}*/ - -//void CSession::EncryptUpdate(ByteArray &Data, ByteArray &EncryptedData) -//{ -// init_func - -// // NON SUPPORTATO DALLA CIE -// throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); - -/*if (pEncryptMechanism == nullptr) - throw p11_error(CKR_OPERATION_NOT_INITIALIZED); - -ByteDynArray baEncryptedData = pEncryptMechanism->EncryptUpdate(Data); -if (!EncryptedData.isNull() && EncryptedData.size() < baEncryptedData.size()) - throw p11_error(CKR_BUFFER_TOO_SMALL); -EncryptedData = EncryptedData.left(baEncryptedData.size()); -if (EncryptedData.isNull()) - return; -EncryptedData.copy(baEncryptedData);*/ -//} - -//void CSession::EncryptFinal(ByteArray &EncryptedData) -//{ -// init_func - -// // NON SUPPORTATO DALLA CIE -// throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); - -/*if (pEncryptMechanism == nullptr) - throw p11_error(CKR_OPERATION_NOT_INITIALIZED); - -auto mech = make_resetter(pEncryptMechanism); -CK_ULONG ulReqLen = pEncryptMechanism->EncryptLength(); - -if (!EncryptedData.isNull() && EncryptedData.size()EncryptFinal(); - -EncryptedData.copy(baEncryptedBuffer); -*/ -//} - -/* ******************** */ -/* Decrypt */ -/* ******************** */ - -//void CSession::DecryptInit(CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) -//{ -// init_func - -// // NON SUPPORTATO DALLA CIE -// throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); - - -//if (pDecryptMechanism != nullptr) -// throw p11_error(CKR_OPERATION_ACTIVE); - -//std::shared_ptr pObject = pSlot->GetObjectFromID(hKey); -//if (pObject == nullptr) -// throw p11_error(CKR_KEY_HANDLE_INVALID); -//if (pObject->ObjClass != CKO_PRIVATE_KEY) -// throw p11_error(CKR_KEY_HANDLE_INVALID); -//auto pDecryptKey = std::static_pointer_cast(pObject); - -// -//if (pDecryptKey->IsPrivate() && pSlot->User != CKU_USER) -// throw p11_error(CKR_USER_NOT_LOGGED_IN); - -//ByteArray *baAttrVal = pDecryptKey->getAttribute(CKA_DECRYPT); -//if (baAttrVal == nullptr) -// throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); -// else { -// if (ByteArrayToVar(*baAttrVal, CK_BBOOL) == FALSE) -// throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); -// } - -//switch (pMechanism->mechanism) { -//case CKM_RSA_PKCS: -//{ -// auto mech = std::unique_ptr(new CRSA_PKCS1(shared_from_this())); -// mech->DecryptInit(hKey); -// pDecryptMechanism = std::move(mech); -// break; -//} -///* NON SUPPORTATO DALLA CIE -//case CKM_RSA_X_509: -//{ -// auto mech = std::unique_ptr(new CRSA_X509(shared_from_this())); -// mech->DecryptInit(hKey); -// pDecryptMechanism = std::move(mech); -// break; -//}*/ -//default: -// throw p11_error(CKR_MECHANISM_INVALID); -//} - -//} - -//void CSession::Decrypt(ByteArray &EncryptedData, ByteArray &Data) -//{ -// init_func - -// // NON SUPPORTATO DALLA CIE -// throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); - -/*if (pDecryptMechanism == nullptr) - throw p11_error(CKR_OPERATION_NOT_INITIALIZED); - -bool bFound = pDecryptMechanism->checkCache(EncryptedData, Data); - -if (bFound) { - pDecryptMechanism.reset(); - return; -} - -DecryptUpdate(EncryptedData, Data); -DecryptFinal(Data); - -if (Data.isNull()) - pDecryptMechanism->cacheData = EncryptedData;*/ -//} - -//void CSession::DecryptUpdate(ByteArray &EncryptedData, ByteArray &Data) -//{ -// init_func - -// // NON SUPPORTATO DALLA CIE -// throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); - -/*if (pDecryptMechanism == nullptr) - throw p11_error(CKR_OPERATION_NOT_INITIALIZED); - -ByteDynArray baData = pDecryptMechanism->DecryptUpdate(EncryptedData); - -if (!Data.isNull() && Data.size() < baData.size()) - throw p11_error(CKR_BUFFER_TOO_SMALL); -Data = Data.left(baData.size()); -if (Data.isNull()) - return; -Data.copy(baData);*/ -//} - -//void CSession::DecryptFinal(ByteArray &Data) -//{ -// init_func - -// // NON SUPPORTATO DALLA CIE -// throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); - -/*if (pDecryptMechanism == nullptr) - throw p11_error(CKR_OPERATION_NOT_INITIALIZED); - -auto mech = make_resetter(pDecryptMechanism); -bool bFound = pDecryptMechanism->checkCache(ByteArray(), Data); - -if (bFound) - return; - -std::shared_ptr pObject = pSlot->GetObjectFromID(pDecryptMechanism->hDecryptKey); -if (pObject == nullptr) - throw p11_error(CKR_KEY_HANDLE_INVALID); -if (pObject->ObjClass != CKO_PRIVATE_KEY) - throw p11_error(CKR_KEY_HANDLE_INVALID); -auto pDecryptKey = std::static_pointer_cast(pObject); - -if (pDecryptKey->IsPrivate() && pSlot->User != CKU_USER) - throw p11_error(CKR_USER_NOT_LOGGED_IN); - -ByteArray *baKeyModule = pDecryptKey->getAttribute(CKA_MODULUS); -ER_ASSERT(baKeyModule != nullptr, ERR_CANT_GET_PUBKEY_MODULUS) - -size_t dwKeyLenBytes = baKeyModule->size(); - -ByteDynArray baDecryptBuffer = pDecryptMechanism->DecryptFinal(); - -ByteDynArray baData; -pSlot->pTemplate->FunctionList.templateDecrypt(pSlot->pTemplateData, pDecryptKey.get(), baDecryptBuffer, baData, pDecryptMechanism->mtType, false); - -ByteDynArray baUnpaddedData = pDecryptMechanism->DecryptRemovePadding(baData); - -if (Data.isNull()) { - pDecryptMechanism->setCache(ByteArray(), baUnpaddedData); - Data = ByteArray(nullptr, baUnpaddedData.size()); - mech.release(); -} -else if (Data.size()setCache(ByteArray(), baUnpaddedData); - Data = Data.left(baUnpaddedData.size()); - mech.release(); - throw p11_error(CKR_BUFFER_TOO_SMALL); -} -else { - pDecryptMechanism->setCache(ByteArray(), baUnpaddedData); - Data.copy(baUnpaddedData); - Data = Data.left(baUnpaddedData.size()); -}*/ -//} - -void CSession::GenerateRandom(ByteArray &RandomData) { - init_func - ByteDynArray baRandom(RandomData.size()); - pSlot->pTemplate->FunctionList.templateGenerateRandom(pSlot->pTemplateData, baRandom); - RandomData.copy(baRandom); -} - -void CSession::InitPIN(ByteArray &Pin) { - init_func - - if (pSlot->User != CKU_SO) - throw p11_error(CKR_USER_NOT_LOGGED_IN); - - pSlot->pTemplate->FunctionList.templateInitPIN(pSlot->pTemplateData, Pin); -} - -void CSession::SetPIN(ByteArray &OldPin, ByteArray &NewPin) { - init_func - - pSlot->pTemplate->FunctionList.templateSetPIN(pSlot->pTemplateData, OldPin, NewPin, pSlot->User); -} - -CK_ULONG CSession::GetObjectSize(CK_OBJECT_HANDLE hObject) { - init_func - - std::shared_ptr pObject = pSlot->GetObjectFromID(hObject); - if (pObject == nullptr) - throw p11_error(CKR_OBJECT_HANDLE_INVALID); - - - if (pObject->IsPrivate() && pSlot->User != CKU_USER) - throw p11_error(CKR_USER_NOT_LOGGED_IN); - - return pObject->GetObjectSize(); -} - -void CSession::SetAttributeValue(CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { - init_func - std::shared_ptr pObject = pSlot->GetObjectFromID(hObject); - if (pObject == nullptr) - throw p11_error(CKR_OBJECT_HANDLE_INVALID); - - if ((flags & CKF_RW_SESSION) == 0) - throw p11_error(CKR_SESSION_READ_ONLY); - - if (pSlot->User != CKU_USER) - throw p11_error(CKR_USER_NOT_LOGGED_IN); - - pSlot->pTemplate->FunctionList.templateSetAttribute(pSlot->pTemplateData, pObject.get(), pTemplate, ulCount); -} - -void CSession::SetOperationState(ByteArray &OperationState) { - init_func - CTLV Tlv(OperationState); - - ByteArray Flags, User; - Flags = Tlv.getValue(OS_Flags); - if (Flags.isNull()) throw p11_error(CKR_SAVED_STATE_INVALID); - User = Tlv.getValue(OS_User); - if (User.isNull()) - throw p11_error(CKR_SAVED_STATE_INVALID); - - if (Flags != VarToByteArray(flags)) - throw p11_error(CKR_SAVED_STATE_INVALID); - if (User != VarToByteArray(pSlot->User)) - throw p11_error(CKR_SAVED_STATE_INVALID); - - ByteArray SignOperationState = Tlv.getValue(OS_Sign); - if (!SignOperationState.isNull()) { - pSignMechanism.reset(); - CTLV SignTlv(SignOperationState); - ByteArray Algo = SignTlv.getValue(OS_Algo); - if (Algo.isNull()) - throw p11_error(CKR_SAVED_STATE_INVALID); - CK_MECHANISM mech = { ByteArrayToVar(Algo, CK_MECHANISM_TYPE), NULL, 0 }; - - ByteArray Key = SignTlv.getValue(OS_Key); - if (Key.isNull()) - throw p11_error(CKR_SAVED_STATE_INVALID); - - std::shared_ptr pKey = pSlot->FindP11Object(CKO_PRIVATE_KEY, CKA_ID, Key.data(), (int)Key.size()); - ER_ASSERT(pKey != nullptr, ERR_CANT_GET_OBJECT); - CK_OBJECT_HANDLE hKey = pSlot->GetIDFromObject(pKey); - - ByteArray Data = SignTlv.getValue(OS_Data); - if (Data.isNull()) - throw p11_error(CKR_SAVED_STATE_INVALID); - - SignInit(&mech, hKey); - pSignMechanism->SignSetOperationState(Data); - } - - /*ByteArray DecryptOperationState = Tlv.getValue(OS_Decrypt); - if (!DecryptOperationState.isNull()) { - pDecryptMechanism.reset(); - CTLV DecryptTlv(DecryptOperationState); - ByteArray Algo = DecryptTlv.getValue(OS_Algo); - throw p11_error(CKR_SAVED_STATE_INVALID); - CK_MECHANISM mech = { ByteArrayToVar(Algo, CK_MECHANISM_TYPE), NULL, 0 }; - - ByteArray Key = DecryptTlv.getValue(OS_Key); - if (Key.isNull()) - throw p11_error(CKR_SAVED_STATE_INVALID); - - std::shared_ptr pKey = pSlot->FindP11Object(CKO_PRIVATE_KEY, CKA_ID, Key.data(), (int)Key.size()); - ER_ASSERT(pKey != nullptr, ERR_CANT_GET_OBJECT) - CK_OBJECT_HANDLE hKey = pSlot->GetIDFromObject(pKey); - - ByteArray Data = DecryptTlv.getValue(OS_Data); - if (Data.isNull()) - throw p11_error(CKR_SAVED_STATE_INVALID); - - DecryptInit(&mech, hKey); - pDecryptMechanism->DecryptSetOperationState(Data); - }*/ - - ByteArray VerifyOperationState = Tlv.getValue(OS_Verify); - if (!VerifyOperationState.isNull()) { - pVerifyMechanism.reset(); - CTLV VerifyTlv(VerifyOperationState); - ByteArray Algo = VerifyTlv.getValue(OS_Algo); - if (Algo.isNull()) - throw p11_error(CKR_SAVED_STATE_INVALID); - CK_MECHANISM mech = { ByteArrayToVar(Algo, CK_MECHANISM_TYPE), NULL, 0 }; - - ByteArray Key = VerifyTlv.getValue(OS_Key); - if (Key.isNull()) - throw p11_error(CKR_SAVED_STATE_INVALID); - - std::shared_ptr pKey = pSlot->FindP11Object(CKO_PUBLIC_KEY, CKA_ID, Key.data(), (int)Key.size()); - ER_ASSERT(pKey != nullptr, ERR_CANT_GET_OBJECT) - CK_OBJECT_HANDLE hKey = pSlot->GetIDFromObject(pKey); - - ByteArray Data = VerifyTlv.getValue(OS_Data); - if (Data.isNull()) - throw p11_error(CKR_SAVED_STATE_INVALID); - - VerifyInit(&mech, hKey); - - pVerifyMechanism->VerifySetOperationState(Data); - } - - ByteArray EncryptOperationState = Tlv.getValue(OS_Encrypt); - /*if (!EncryptOperationState.isNull()) { - pEncryptMechanism.reset(); - CTLV EncryptTlv(EncryptOperationState); - ByteArray Algo = EncryptTlv.getValue(OS_Algo); - if (Algo.isNull()) - throw p11_error(CKR_SAVED_STATE_INVALID); - CK_MECHANISM mech = { ByteArrayToVar(Algo, CK_MECHANISM_TYPE), NULL, 0 }; - - ByteArray Key = EncryptTlv.getValue(OS_Key); - if (Key.isNull()) - throw p11_error(CKR_SAVED_STATE_INVALID); - - std::shared_ptr pKey = pSlot->FindP11Object(CKO_PUBLIC_KEY, CKA_ID, Key.data(), (int)Key.size()); - ER_ASSERT(pKey != nullptr, ERR_CANT_GET_OBJECT); - CK_OBJECT_HANDLE hKey = pSlot->GetIDFromObject(pKey); - - ByteArray Data = EncryptTlv.getValue(OS_Data); - if (Data.isNull()) - throw p11_error(CKR_SAVED_STATE_INVALID); - - EncryptInit(&mech, hKey); - - pEncryptMechanism->EncryptSetOperationState(Data); - }*/ - - ByteArray DigestOperationState = Tlv.getValue(OS_Digest); - if (!DigestOperationState.isNull()) { - pDigestMechanism.reset(); - CTLV DigestTlv(DigestOperationState); - ByteArray Algo = DigestTlv.getValue(OS_Algo); - if (Algo.isNull()) - throw p11_error(CKR_SAVED_STATE_INVALID); - CK_MECHANISM mech = { ByteArrayToVar(Algo, CK_MECHANISM_TYPE), NULL, 0 }; - - ByteArray Data = DigestTlv.getValue(OS_Data); - if (Data.isNull()) - throw p11_error(CKR_SAVED_STATE_INVALID); - - DigestInit(&mech); - - pDigestMechanism->DigestSetOperationState(Data); - } -} - -void CSession::GetOperationState(ByteArray &OperationState) { - init_func - - CTLVCreate Tlv; - ByteArray ba1((BYTE*)&flags, sizeof(flags)); - Tlv.setValue(OS_Flags, ba1); - ByteArray ba2((BYTE*)&flags, sizeof(flags)); - Tlv.setValue(OS_User, ba2); - if (pSignMechanism) { - CTLVCreate SignTlv; - ByteArray ba3((BYTE*)&pSignMechanism->mtType, sizeof(pSignMechanism->mtType)); - SignTlv.setValue(OS_Algo, ba3); - ByteDynArray SignData = pSignMechanism->SignGetOperationState(); - if (!SignData.isEmpty()) - SignTlv.setValue(OS_Data, SignData); - - std::shared_ptr pKey = pSlot->GetObjectFromID(pSignMechanism->hSignKey); - ER_ASSERT(pKey != nullptr, ERR_CANT_GET_OBJECT); - ByteArray *SignKeyID = pKey->getAttribute(CKA_ID); - ER_ASSERT(SignKeyID != nullptr, ERR_CANT_FIND_ID); - SignTlv.setValue(OS_Key, *SignKeyID); - - ByteDynArray *SignOperationState = Tlv.addValue(OS_Sign); - *SignOperationState = SignTlv.getBuffer(); - } - if (pVerifyMechanism) { - CTLVCreate VerifyTlv; - ByteArray ba((BYTE*)&pVerifyMechanism->mtType, sizeof(pVerifyMechanism->mtType)); - VerifyTlv.setValue(OS_Algo, ba); - ByteDynArray verifyData = pVerifyMechanism->VerifyGetOperationState(); - if (!verifyData.isEmpty()) - VerifyTlv.setValue(OS_Data, verifyData); - - - std::shared_ptr pKey = pSlot->GetObjectFromID(pVerifyMechanism->hVerifyKey); - ER_ASSERT(pKey != nullptr, ERR_CANT_GET_OBJECT); - ByteArray *VerifyKeyID = pKey->getAttribute(CKA_ID); - ER_ASSERT(VerifyKeyID != nullptr, ERR_CANT_FIND_ID); - VerifyTlv.setValue(OS_Key, *VerifyKeyID); - - ByteDynArray *VerifyOperationState = Tlv.addValue(OS_Verify); - *VerifyOperationState = VerifyTlv.getBuffer(); - } - if (pDigestMechanism) { - CTLVCreate DigestTlv; - ByteArray ba((BYTE*)&pDigestMechanism->mtType, sizeof(pDigestMechanism->mtType)); - DigestTlv.setValue(OS_Algo, ba); - ByteDynArray DigestData = pDigestMechanism->DigestGetOperationState(); - if (!DigestData.isEmpty()) - DigestTlv.setValue(OS_Data, DigestData); - - ByteDynArray *DigestOperationState = Tlv.addValue(OS_Digest); - *DigestOperationState = DigestTlv.getBuffer(); - } - /*if (pEncryptMechanism) { - CTLVCreate EncryptTlv; - EncryptTlv.setValue(OS_Algo, ByteArray((BYTE*)&pEncryptMechanism->mtType, sizeof(pEncryptMechanism->mtType))); - ByteDynArray EncryptData = pEncryptMechanism->EncryptGetOperationState(); - if (!EncryptData.isEmpty()) - EncryptTlv.setValue(OS_Data, EncryptData); - - - std::shared_ptr pKey = pSlot->GetObjectFromID(pEncryptMechanism->hEncryptKey); - ER_ASSERT(pKey != nullptr, ERR_CANT_GET_OBJECT); - ByteArray *EncryptKeyID = pKey->getAttribute(CKA_ID); - ER_ASSERT(EncryptKeyID != nullptr, ERR_CANT_FIND_ID); - EncryptTlv.setValue(OS_Key, *EncryptKeyID); - - ByteDynArray *EncryptOperationState = Tlv.addValue(OS_Encrypt); - *EncryptOperationState = EncryptTlv.getBuffer(); - }*/ - /*if (pDecryptMechanism) { - CTLVCreate DecryptTlv; - DecryptTlv.setValue(OS_Algo, ByteArray((BYTE*)&pDecryptMechanism->mtType, sizeof(pDecryptMechanism->mtType))); - ByteDynArray DecryptData = pDecryptMechanism->DecryptGetOperationState(); - if (!DecryptData.isEmpty()) - DecryptTlv.setValue(OS_Data, DecryptData); - - - std::shared_ptr pKey = pSlot->GetObjectFromID(pDecryptMechanism->hDecryptKey); - ER_ASSERT(pKey != nullptr, ERR_CANT_GET_OBJECT); - ByteArray *DecryptKeyID = pKey->getAttribute(CKA_ID); - ER_ASSERT(DecryptKeyID != nullptr, ERR_CANT_FIND_ID); - DecryptTlv.setValue(OS_Key, *DecryptKeyID); - - ByteDynArray *DecryptOperationState = Tlv.addValue(OS_Decrypt); - *DecryptOperationState = DecryptTlv.getBuffer(); - }*/ - ByteDynArray newOperationState = Tlv.getBuffer(); - - if (newOperationState.size() == 0) - throw p11_error(CKR_OPERATION_NOT_INITIALIZED); - - if (OperationState.isNull()) { - OperationState = ByteArray(nullptr, newOperationState.size()); - return; - } - if (OperationState.size() < newOperationState.size()) - throw p11_error(CKR_BUFFER_TOO_SMALL); - - OperationState.copy(newOperationState); -} -}; +//#include "../StdAfx.h" +#include "session.h" +#include "CardTemplate.h" +#include "../Util/util.h" +#include "../Crypto/RSA.h" +#include "../Util/TLV.h" + +extern CLog Log; + +namespace { +template +class resetter; + +template +resetter make_resetter(T&) noexcept; + +template +class resetter> { + private: + std::unique_ptr * m_p; + + friend resetter> make_resetter>(std::unique_ptr& p) noexcept; + resetter(std::unique_ptr& p) noexcept : m_p(&p) {} + + void reset() noexcept(noexcept(m_p->reset())) { + if (m_p) + m_p->reset(); + + m_p = nullptr; + } + + public: + resetter(const resetter&) = delete; + resetter(resetter&& other) noexcept : m_p(std::exchange(other.m_p, nullptr)) {} + + resetter& operator=(const resetter&) = delete; + + resetter& operator=(resetter&& other) noexcept(noexcept(reset())) { + reset(); + m_p = std::exchange(other.m_p, nullptr); + return *this; + } + + ~resetter() { //noexcept(noexcept(reset())) + reset(); + } + + void release() noexcept { + m_p = nullptr; + } +}; + +template +resetter make_resetter(T& p) noexcept { + return resetter(p); +} + +} + +namespace p11 { + +DWORD CSession::dwSessionCnt = 0; +SessionMap CSession::g_mSessions; + +CSession::CSession() { + pSlot = NULL; + bFindInit = false; +} + + +CK_SLOT_ID CSession::GetNewSessionID() { + init_func + dwSessionCnt++; + __sync_fetch_and_add(&dwSessionCnt, 1); + return dwSessionCnt; +} + +CK_SESSION_HANDLE CSession::AddSession(std::unique_ptr pSession) { + init_func + pSession->hSessionHandle = GetNewSessionID(); + auto id = pSession->hSessionHandle; + + pSession->pSlot->pTemplate->FunctionList.templateInitSession(pSession->pSlot->pTemplateData); + + pSession->pSlot->dwSessionCount++; + g_mSessions.insert(std::make_pair(pSession->hSessionHandle, std::move(pSession))); + + return id; +} + +void CSession::DeleteSession(CK_SESSION_HANDLE hSessionHandle) { + init_func + std::shared_ptr pSession=GetSessionFromID(hSessionHandle); + + ER_ASSERT(pSession != nullptr, ERR_SESSION_NOT_OPENED); + + pSession->pSlot->dwSessionCount--; + if (pSession->pSlot->dwSessionCount == 0) { + if (pSession->pSlot->User != CKU_NOBODY) { + pSession->Logout(); + } + } + + pSession->pSlot->pTemplate->FunctionList.templateFinalSession(pSession->pSlot->pTemplateData); + g_mSessions.erase(hSessionHandle); +} + +std::shared_ptr CSession::GetSessionFromID(CK_SESSION_HANDLE hSessionHandle) { + init_func + SessionMap::const_iterator pPair; + pPair = g_mSessions.find(hSessionHandle); + if (pPair == g_mSessions.end()) + return nullptr; + + return pPair->second; +} + +/* ******************* */ +/* LOGIN e LOGOUT */ +/* ******************* */ + +void CSession::Login(CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG ulPinLen) { + init_func + + if (pSlot->User == CKU_USER && userType == CKU_SO) + throw p11_error(CKR_USER_ANOTHER_ALREADY_LOGGED_IN); + if (pSlot->User == CKU_SO && userType == CKU_USER) + throw p11_error(CKR_USER_ANOTHER_ALREADY_LOGGED_IN); + bool bExistsRO = false; + if (userType == CKU_SO) { + if (ExistsRO()) + throw p11_error(CKR_SESSION_READ_ONLY_EXISTS); + } + if (pSlot->User != CKU_NOBODY) + throw p11_error(CKR_USER_ALREADY_LOGGED_IN); + + ByteArray baPin(pPin, ulPinLen); + pSlot->pTemplate->FunctionList.templateLogin(pSlot->pTemplateData, userType, baPin); + + pSlot->User = userType; +} + +void CSession::Logout() { + init_func + + pSlot->pTemplate->FunctionList.templateLogout(pSlot->pTemplateData, pSlot->User); + + for (auto obj = pSlot->P11Objects.begin(); obj != pSlot->P11Objects.end(); obj++) { + if ((*obj)->IsPrivate()) + pSlot->DelObjectHandle(*obj); + } + pSlot->User = CKU_NOBODY; +} + +/* ******************* */ +/* Find Objects */ +/* ******************* */ + +void CSession::FindObjectsInit(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { + init_func + if (bFindInit) + throw p11_error(CKR_OPERATION_ACTIVE); + findResult.clear(); + if (ulCount == 0) { + for (auto obj = pSlot->P11Objects.begin(); obj != pSlot->P11Objects.end(); obj++) { + try { + findResult.push_back(pSlot->GetIDFromObject(*obj)); + } catch (p11_error &err) { + if (err.getP11ErrorCode() != CKR_USER_NOT_LOGGED_IN) + throw; + } + } + } else { + for (auto obj = pSlot->P11Objects.begin(); obj != pSlot->P11Objects.end(); obj++) { + bool bSkip = false; + + for (unsigned int j = 0; j < ulCount && !bSkip; j++) { + try { + ByteArray* attr = (*obj)->getAttribute(pTemplate[j].type); + if (attr==nullptr) + bSkip = true; + else { + if (attr->size() != pTemplate[j].ulValueLen) + bSkip = true; + else if ((*attr) != ByteArray((BYTE*)pTemplate[j].pValue, pTemplate[j].ulValueLen)) + bSkip = true; + } + } catch (p11_error &err) { + if (err.getP11ErrorCode() != CKR_USER_NOT_LOGGED_IN) + throw; + bSkip = true; + } + } + if (!bSkip) { + try { + findResult.push_back(pSlot->GetIDFromObject(*obj)); + } catch (p11_error &err) { + if (err.getP11ErrorCode() != CKR_USER_NOT_LOGGED_IN) + throw; + } + /*if (Log.LogParam) { + ByteArray *Label = NULL; + pSlot->P11Objects[i]->getAttribute(CKA_LABEL, Label); + //Log.writePure("Object found %i:", i); + //Log.writePure("Class: %x", pSlot->P11Objects[i]->ObjClass); + if (Label) { + //Log.writePure("Label:"); + info.logParameter(Label->data(), Label->size()); + } + }*/ + } + } + } + bFindInit = true; +} + +void CSession::FindObjects(CK_OBJECT_HANDLE_PTR phObject, CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount) { + init_func + if (!bFindInit) + throw p11_error(CKR_OPERATION_NOT_INITIALIZED); + *pulObjectCount = 0; + int iCnt = 0; + while (!findResult.empty() && ulMaxObjectCount>0) { + phObject[iCnt] = findResult.back(); + findResult.pop_back(); + iCnt++; + ulMaxObjectCount--; + } + *pulObjectCount = iCnt; +} + +void CSession::FindObjectsFinal() { + init_func + if (!bFindInit) + throw p11_error(CKR_OPERATION_NOT_INITIALIZED); + findResult.clear(); + bFindInit = false; +} + +CK_RV CSession::GetAttributeValue(CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { + init_func + + std::shared_ptr pObject = pSlot->GetObjectFromID(hObject); + if (pObject == nullptr) + throw p11_error(CKR_OBJECT_HANDLE_INVALID); + + return pObject->GetAttributeValue(pTemplate, ulCount); +} + +ByteDynArray GetTemplateValue(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_ATTRIBUTE_TYPE type) { + init_func + for (unsigned int i = 0; iUser != CKU_USER) + throw p11_error(CKR_USER_NOT_LOGGED_IN); + + std::shared_ptr pObject = pSlot->pTemplate->FunctionList.templateCreateObject(pSlot->pTemplateData, pTemplate, ulCount); + + if (pObject != nullptr) + return pSlot->GetIDFromObject(pObject); + else + throw p11_error(CKR_GENERAL_ERROR); + +} + +CK_OBJECT_HANDLE CSession::GenerateKey(CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { + init_func + + // NON SUPPORTATO DALLA CIE + throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); + + /*if ((flags & CKF_RW_SESSION) == 0) + throw p11_error(CKR_SESSION_READ_ONLY); + + if (pSlot->User != CKU_USER) + throw p11_error(CKR_USER_NOT_LOGGED_IN); + + std::shared_ptr pKey = pSlot->pTemplate->FunctionList.templateGenerateKey(pSlot->pTemplateData, pMechanism, pTemplate, ulCount); + + if (pKey != nullptr) { + return pSlot->GetIDFromObject(pKey); + } + else + throw p11_error(CKR_GENERAL_ERROR);*/ +} + +void CSession::GenerateKeyPair(CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey) { + init_func + + // NON SUPPORTATO DALLA CIE + throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); + + /* if ((flags & CKF_RW_SESSION) == 0) + throw p11_error(CKR_SESSION_READ_ONLY); + + if (pSlot->User != CKU_USER) + throw p11_error(CKR_USER_NOT_LOGGED_IN); + + std::shared_ptr pPublicKey = nullptr; + std::shared_ptr pPrivateKey = nullptr; + pSlot->pTemplate->FunctionList.templateGenerateKeyPair(pSlot->pTemplateData, pMechanism, pPublicKeyTemplate, ulPublicKeyAttributeCount, pPrivateKeyTemplate, ulPrivateKeyAttributeCount, pPublicKey, pPrivateKey); + + if (pPublicKey != nullptr) { + *phPublicKey = pSlot->GetIDFromObject(pPublicKey); + } + else + throw p11_error(CKR_GENERAL_ERROR); + + if (pPrivateKey != nullptr) { + *phPrivateKey = pSlot->GetIDFromObject(pPrivateKey); + } + else + throw p11_error(CKR_GENERAL_ERROR); + */ +} + +void CSession::DestroyObject(CK_OBJECT_HANDLE hObject) { + init_func + + if ((flags & CKF_RW_SESSION) == 0) + throw p11_error(CKR_SESSION_READ_ONLY); + + if (pSlot->User != CKU_USER) + throw p11_error(CKR_USER_NOT_LOGGED_IN); + + std::shared_ptr pObject = pSlot->GetObjectFromID(hObject); + if (pObject == nullptr) + throw p11_error(CKR_OBJECT_HANDLE_INVALID); + + pSlot->pTemplate->FunctionList.templateDestroyObject(pSlot->pTemplateData, *pObject); + pSlot->DelP11Object(pObject); +} + +bool CSession::ExistsRO() { + init_func + for (SessionMap::const_iterator it = g_mSessions.begin(); it != g_mSessions.end(); it++) { + if (it->second->pSlot == pSlot && (it->second->flags & CKF_RW_SESSION) == 0) { + return true; + } + } + + return false; +} + +bool CSession::ExistsSO_RW() { + init_func + if (pSlot->User != CKU_SO) + return false; + for (SessionMap::const_iterator it = g_mSessions.begin(); it != g_mSessions.end(); it++) { + if (it->second->pSlot == pSlot && (it->second->flags & CKF_RW_SESSION) != 0) + return true; + } + + return false; +} + +/* ******************* */ +/* Digest */ +/* ******************* */ + +void CSession::DigestInit(CK_MECHANISM_PTR pMechanism) { + init_func + if (pDigestMechanism != nullptr) + throw p11_error(CKR_OPERATION_ACTIVE); + + switch (pMechanism->mechanism) { + case CKM_SHA_1: { + auto mech = std::unique_ptr(new CDigestSHA(shared_from_this())); + mech->DigestInit(); + + pDigestMechanism = std::move(mech); + break; + } + case CKM_SHA256: { + auto mech = std::unique_ptr(new CDigestSHA256(shared_from_this())); + mech->DigestInit(); + + pDigestMechanism = std::move(mech); + break; + } + case CKM_MD5: { + auto mech = std::unique_ptr(new CDigestMD5(shared_from_this())); + mech->DigestInit(); + + pDigestMechanism = std::move(mech); + break; + } + default: + throw p11_error(CKR_MECHANISM_INVALID); + } +} + +void CSession::Digest(ByteArray &Data, ByteArray &Digest) { + init_func + + CK_ULONG ulReqLen = pDigestMechanism->DigestLength(); + + if (!Digest.isNull() && Digest.size() < ulReqLen) + throw p11_error(CKR_BUFFER_TOO_SMALL); + + Digest = Digest.left(ulReqLen); + if (Digest.isNull()) + return; + + DigestUpdate(Data); + DigestFinal(Digest); + +} + +void CSession::DigestUpdate(ByteArray &Data) { + init_func + if (pDigestMechanism==nullptr) + throw p11_error(CKR_OPERATION_NOT_INITIALIZED); + + pDigestMechanism->DigestUpdate(Data); +} + +void CSession::DigestFinal(ByteArray &Digest) { + init_func + if (pDigestMechanism == nullptr) + throw p11_error(CKR_OPERATION_NOT_INITIALIZED); + + auto mech = std::move(pDigestMechanism); + CK_ULONG ulReqLen = mech->DigestLength(); + + if (!Digest.isNull() && Digest.size()DigestFinal(Digest); + +} + +/* ******************* */ +/* Verify */ +/* ******************* */ + +void CSession::VerifyInit(CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { + init_func + if (pVerifyMechanism != nullptr) + throw p11_error(CKR_OPERATION_ACTIVE); + + std::shared_ptr pObject = pSlot->GetObjectFromID(hKey); + if (pObject == nullptr) + throw p11_error(CKR_KEY_HANDLE_INVALID); + if (pObject->ObjClass != CKO_PUBLIC_KEY) + throw p11_error(CKR_KEY_HANDLE_INVALID); + auto pVerifyKey = std::static_pointer_cast(pObject); + + + if (pVerifyKey->IsPrivate() && pSlot->User != CKU_USER) + throw p11_error(CKR_USER_NOT_LOGGED_IN); + + ByteArray *baAttrVal = pVerifyKey->getAttribute(CKA_VERIFY); + if (baAttrVal==nullptr) + throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); + else { + if (ByteArrayToVar(*baAttrVal, CK_BBOOL) == FALSE) + throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); + } + + switch (pMechanism->mechanism) { + case CKM_SHA1_RSA_PKCS: { + auto mech = std::unique_ptr(new CRSAwithSHA1(shared_from_this())); + mech->VerifyInit(hKey); + pVerifyMechanism = std::move(mech); + break; + } + case CKM_SHA256_RSA_PKCS: { + auto mech = std::unique_ptr(new CRSAwithSHA256(shared_from_this())); + mech->VerifyInit(hKey); + pVerifyMechanism = std::move(mech); + break; + } + case CKM_MD5_RSA_PKCS: { + auto mech = std::unique_ptr(new CRSAwithMD5(shared_from_this())); + mech->VerifyInit(hKey); + pVerifyMechanism = std::move(mech); + break; + } + case CKM_RSA_PKCS: { + auto mech = std::unique_ptr(new CRSA_PKCS1(shared_from_this())); + mech->VerifyInit(hKey); + pVerifyMechanism = std::move(mech); + break; + } + /* NON SUPPORTATO DALLA CIE + case CKM_RSA_X_509: + { + auto mech = std::unique_ptr(new CRSA_X509(shared_from_this())); + mech->VerifyInit(hKey); + pVerifyMechanism = std::move(mech); + break; + }*/ + default: + throw p11_error(CKR_MECHANISM_INVALID); + } +} + +void CSession::Verify(ByteArray &Data, ByteArray &Signature) { + init_func + + if (pVerifyMechanism == nullptr) + throw p11_error(CKR_OPERATION_NOT_INITIALIZED); + + VerifyUpdate(Data); + VerifyFinal(Signature); +} + +void CSession::VerifyUpdate(ByteArray &Data) { + init_func + if (pVerifyMechanism == nullptr) + throw p11_error(CKR_OPERATION_NOT_INITIALIZED); + + pVerifyMechanism->VerifyUpdate(Data); +} + +void CSession::VerifyFinal(ByteArray &Signature) { + init_func + if (pVerifyMechanism == nullptr) + throw p11_error(CKR_OPERATION_NOT_INITIALIZED); + + auto mech = make_resetter(pVerifyMechanism); + pVerifyMechanism->VerifyFinal(Signature); +} + +/* ******************** */ +/* VerifyRecover */ +/* ******************** */ + +void CSession::VerifyRecoverInit(CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { + init_func + if (pVerifyRecoverMechanism!= nullptr) + throw p11_error(CKR_OPERATION_ACTIVE); + + std::shared_ptr pObject = pSlot->GetObjectFromID(hKey); + if (pObject == NULL) + throw p11_error(CKR_KEY_HANDLE_INVALID); + if (pObject->ObjClass != CKO_PUBLIC_KEY) + throw p11_error(CKR_KEY_HANDLE_INVALID); + auto pVerifyRecoverKey = std::static_pointer_cast(pObject); + + + if (pVerifyRecoverKey->IsPrivate() && pSlot->User != CKU_USER) + throw p11_error(CKR_USER_NOT_LOGGED_IN); + + ByteArray *baAttrVal = pVerifyRecoverKey->getAttribute(CKA_VERIFY_RECOVER); + if (baAttrVal==nullptr) + throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); + else { + if (ByteArrayToVar(*baAttrVal, CK_BBOOL) == FALSE) + throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); + } + + switch (pMechanism->mechanism) { + case CKM_RSA_PKCS: { + auto mech = std::unique_ptr(new CRSA_PKCS1(shared_from_this())); + mech->VerifyRecoverInit(hKey); + pVerifyRecoverMechanism = std::move(mech); + break; + } + /* NON SUPPORTATO DALLA CIE + case CKM_RSA_X_509: + { + auto mech = std::unique_ptr(new CRSA_X509(shared_from_this())); + mech->VerifyRecoverInit(hKey); + pVerifyRecoverMechanism = std::move(mech); + break; + }*/ + default: + throw p11_error(CKR_MECHANISM_INVALID); + } +} + +void CSession::VerifyRecover(ByteArray &Signature, ByteArray &Data) { + init_func + if (pVerifyRecoverMechanism == nullptr) + throw p11_error(CKR_OPERATION_NOT_INITIALIZED); + + auto mech = std::move(pVerifyRecoverMechanism); + + CK_ULONG ulKeyLen = pVerifyRecoverMechanism->VerifyRecoverLength(); + ByteDynArray baData = pVerifyRecoverMechanism->VerifyRecover(Signature); + + if (!Data.isNull() && Data.size() pObject = pSlot->GetObjectFromID(hKey); + if (pObject == nullptr) + throw p11_error(CKR_KEY_HANDLE_INVALID); + if (pObject->ObjClass != CKO_PRIVATE_KEY) + throw p11_error(CKR_KEY_HANDLE_INVALID); + auto pSignKey = std::static_pointer_cast(pObject); + + + if (pSignKey->IsPrivate() && pSlot->User != CKU_USER) + throw p11_error(CKR_USER_NOT_LOGGED_IN); + + ByteArray *baAttrVal = pSignKey->getAttribute(CKA_SIGN); + if (baAttrVal==nullptr) + throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); + else { + if (ByteArrayToVar(*baAttrVal, CK_BBOOL) == FALSE) + throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); + } + + switch (pMechanism->mechanism) { + case CKM_SHA1_RSA_PKCS: { + auto mech = std::unique_ptr(new CRSAwithSHA1(shared_from_this())); + mech->SignInit(hKey); + pSignMechanism = std::move(mech); + break; + } + case CKM_SHA256_RSA_PKCS: { + auto mech = std::unique_ptr(new CRSAwithSHA256(shared_from_this())); + mech->SignInit(hKey); + pSignMechanism = std::move(mech); + break; + } + case CKM_MD5_RSA_PKCS: { + auto mech = std::unique_ptr(new CRSAwithMD5(shared_from_this())); + mech->SignInit(hKey); + pSignMechanism = std::move(mech); + break; + } + case CKM_RSA_PKCS: { + auto mech = std::unique_ptr(new CRSA_PKCS1(shared_from_this())); + mech->SignInit(hKey); + pSignMechanism = std::move(mech); + break; + } + /* NON SUPPORTATO DALLA CIE + case CKM_RSA_X_509: + { + auto mech = std::unique_ptr(new CRSA_X509(shared_from_this())); + mech->SignInit(hKey); + pSignMechanism = std::move(mech); + break; + }*/ + default: + throw p11_error(CKR_MECHANISM_INVALID); + } +} + +void CSession::Sign(ByteArray &Data, ByteArray &Signature) { + init_func + if (pSignMechanism == nullptr) + throw p11_error(CKR_OPERATION_NOT_INITIALIZED); + + pSignMechanism->SignReset(); + SignUpdate(Data); + SignFinal(Signature); +} + +void CSession::SignUpdate(ByteArray &Data) { + init_func + if (pSignMechanism == nullptr) + throw p11_error(CKR_OPERATION_NOT_INITIALIZED); + + pSignMechanism->SignUpdate(Data); +} + +void CSession::SignFinal(ByteArray &Signature) { + init_func + if (pSignMechanism == nullptr) + throw p11_error(CKR_OPERATION_NOT_INITIALIZED); + + auto mech = make_resetter(pSignMechanism); + + std::shared_ptr pObject = pSlot->GetObjectFromID(pSignMechanism->hSignKey); + if (pObject == NULL) + throw p11_error(CKR_KEY_HANDLE_INVALID); + if (pObject->ObjClass != CKO_PRIVATE_KEY) + throw p11_error(CKR_KEY_HANDLE_INVALID); + + auto pSignKey = std::static_pointer_cast(pObject); + + if (pSignKey->IsPrivate() && pSlot->User != CKU_USER) + throw p11_error(CKR_USER_NOT_LOGGED_IN); + + if (Signature.isNull()) { + CK_ULONG ulSignLength = pSignMechanism->SignLength(); + Signature = ByteArray(nullptr, ulSignLength); + mech.release(); + return; + } + + ByteDynArray baSignBuffer = pSignMechanism->SignFinal(); + + bool bSilent = false; + ByteDynArray baSignature; + pSlot->pTemplate->FunctionList.templateSign(pSlot->pTemplateData, pSignKey.get(), baSignBuffer, baSignature, pSignMechanism->mtType, bSilent); + + if (Signature.size() pObject = pSlot->GetObjectFromID(hKey); + if (pObject == NULL) + throw p11_error(CKR_KEY_HANDLE_INVALID); + if (pObject->ObjClass != CKO_PRIVATE_KEY) + throw p11_error(CKR_KEY_HANDLE_INVALID); + auto pSignRecoverKey = std::static_pointer_cast(pObject); + + + if (pSignRecoverKey->IsPrivate() && pSlot->User != CKU_USER) + throw p11_error(CKR_USER_NOT_LOGGED_IN); + + ByteArray *baAttrVal = pSignRecoverKey->getAttribute(CKA_SIGN_RECOVER); + if (baAttrVal == nullptr) + throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); + else { + if (ByteArrayToVar(*baAttrVal, CK_BBOOL) == FALSE) + throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); + } + + switch (pMechanism->mechanism) { + case CKM_RSA_PKCS: { + auto mech = std::unique_ptr(new CRSA_PKCS1(shared_from_this())); + mech->SignRecoverInit(hKey); + pSignRecoverMechanism = std::move(mech); + break; + } + /* + NON SUPPORTATO DALLA CIE + case CKM_RSA_X_509: + { + auto mech = std::unique_ptr(new CRSA_X509(shared_from_this())); + mech->SignRecoverInit(hKey); + pSignRecoverMechanism = std::move(mech); + break; + }*/ + default: + throw p11_error(CKR_MECHANISM_INVALID); + } +} + +void CSession::SignRecover(ByteArray &Data, ByteArray &Signature) { + init_func + if (pSignRecoverMechanism == nullptr) + throw p11_error(CKR_OPERATION_NOT_INITIALIZED); + + auto mech = make_resetter(pSignRecoverMechanism); + + std::shared_ptr pObject = pSlot->GetObjectFromID(pSignRecoverMechanism->hSignRecoverKey); + if (pObject == nullptr) + throw p11_error(CKR_KEY_HANDLE_INVALID); + if (pObject->ObjClass != CKO_PRIVATE_KEY) + throw p11_error(CKR_KEY_HANDLE_INVALID); + auto pSignRecoverKey = std::static_pointer_cast(pObject); + + + if (pSignRecoverKey->IsPrivate() && pSlot->User != CKU_USER) + throw p11_error(CKR_USER_NOT_LOGGED_IN); + + if (Signature.isNull()) { + CK_ULONG ulSignRecoverLength = pSignRecoverMechanism->SignRecoverLength(); + Signature = ByteArray(nullptr, ulSignRecoverLength); + mech.release(); + return; + } + + ByteDynArray baSignRecoverBuffer; + pSignRecoverMechanism->SignRecover(Data); + + bool bSilent = false; + + ByteDynArray baSignature; + pSlot->pTemplate->FunctionList.templateSignRecover(pSlot->pTemplateData, pSignRecoverKey.get(), baSignRecoverBuffer, baSignature, pSignRecoverMechanism->mtType, bSilent); + + if (Signature.size() pObject = pSlot->GetObjectFromID(hKey); +//if (pObject == NULL) +// throw p11_error(CKR_KEY_HANDLE_INVALID); +//if (pObject->ObjClass != CKO_PUBLIC_KEY) +// throw p11_error(CKR_KEY_HANDLE_INVALID); +//auto pEncryptKey = std::static_pointer_cast(pObject); + +//if (pEncryptKey->IsPrivate() && pSlot->User != CKU_USER) +// throw p11_error(CKR_USER_NOT_LOGGED_IN); + +//ByteArray *baAttrVal = pEncryptKey->getAttribute(CKA_ENCRYPT); +//if (baAttrVal == nullptr) +// throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); +//else { +// if (ByteArrayToVar(*baAttrVal, CK_BBOOL) == FALSE) +// throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); +//} + +//switch (pMechanism->mechanism) { +//case CKM_RSA_PKCS: +//{ +// auto mech = std::unique_ptr(new CRSA_PKCS1(shared_from_this())); +// mech->EncryptInit(hKey); +// pEncryptMechanism = std::move(mech); +// break; +//} +///* NON SUPPORTATO DALLA CIE +//case CKM_RSA_X_509: +//{ +// auto mech = std::unique_ptr(new CRSA_X509(shared_from_this())); +// mech->EncryptInit(hKey); +// pEncryptMechanism = std::move(mech); +// break; +//}*/ +//default: +// throw p11_error(CKR_MECHANISM_INVALID); +//} +//} + +//void CSession::Encrypt(ByteArray &Data, ByteArray &EncryptedData) +//{ +// init_func + +// // NON SUPPORTATO DALLA CIE +// throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); + +/*if (pEncryptMechanism == nullptr) + throw p11_error(CKR_OPERATION_NOT_INITIALIZED); + +CK_ULONG ulReqLen = pEncryptMechanism->EncryptLength(); + +if (!EncryptedData.isNull() && EncryptedData.size() < ulReqLen) + throw p11_error(CKR_BUFFER_TOO_SMALL); + +EncryptedData = EncryptedData.left(ulReqLen); +if (EncryptedData.isNull()) + return; + +EncryptUpdate(Data, EncryptedData); + +EncryptFinal(EncryptedData);*/ +/*}*/ + +//void CSession::EncryptUpdate(ByteArray &Data, ByteArray &EncryptedData) +//{ +// init_func + +// // NON SUPPORTATO DALLA CIE +// throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); + +/*if (pEncryptMechanism == nullptr) + throw p11_error(CKR_OPERATION_NOT_INITIALIZED); + +ByteDynArray baEncryptedData = pEncryptMechanism->EncryptUpdate(Data); +if (!EncryptedData.isNull() && EncryptedData.size() < baEncryptedData.size()) + throw p11_error(CKR_BUFFER_TOO_SMALL); +EncryptedData = EncryptedData.left(baEncryptedData.size()); +if (EncryptedData.isNull()) + return; +EncryptedData.copy(baEncryptedData);*/ +//} + +//void CSession::EncryptFinal(ByteArray &EncryptedData) +//{ +// init_func + +// // NON SUPPORTATO DALLA CIE +// throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); + +/*if (pEncryptMechanism == nullptr) + throw p11_error(CKR_OPERATION_NOT_INITIALIZED); + +auto mech = make_resetter(pEncryptMechanism); +CK_ULONG ulReqLen = pEncryptMechanism->EncryptLength(); + +if (!EncryptedData.isNull() && EncryptedData.size()EncryptFinal(); + +EncryptedData.copy(baEncryptedBuffer); +*/ +//} + +/* ******************** */ +/* Decrypt */ +/* ******************** */ + +//void CSession::DecryptInit(CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) +//{ +// init_func + +// // NON SUPPORTATO DALLA CIE +// throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); + + +//if (pDecryptMechanism != nullptr) +// throw p11_error(CKR_OPERATION_ACTIVE); + +//std::shared_ptr pObject = pSlot->GetObjectFromID(hKey); +//if (pObject == nullptr) +// throw p11_error(CKR_KEY_HANDLE_INVALID); +//if (pObject->ObjClass != CKO_PRIVATE_KEY) +// throw p11_error(CKR_KEY_HANDLE_INVALID); +//auto pDecryptKey = std::static_pointer_cast(pObject); + +// +//if (pDecryptKey->IsPrivate() && pSlot->User != CKU_USER) +// throw p11_error(CKR_USER_NOT_LOGGED_IN); + +//ByteArray *baAttrVal = pDecryptKey->getAttribute(CKA_DECRYPT); +//if (baAttrVal == nullptr) +// throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); +// else { +// if (ByteArrayToVar(*baAttrVal, CK_BBOOL) == FALSE) +// throw p11_error(CKR_KEY_FUNCTION_NOT_PERMITTED); +// } + +//switch (pMechanism->mechanism) { +//case CKM_RSA_PKCS: +//{ +// auto mech = std::unique_ptr(new CRSA_PKCS1(shared_from_this())); +// mech->DecryptInit(hKey); +// pDecryptMechanism = std::move(mech); +// break; +//} +///* NON SUPPORTATO DALLA CIE +//case CKM_RSA_X_509: +//{ +// auto mech = std::unique_ptr(new CRSA_X509(shared_from_this())); +// mech->DecryptInit(hKey); +// pDecryptMechanism = std::move(mech); +// break; +//}*/ +//default: +// throw p11_error(CKR_MECHANISM_INVALID); +//} + +//} + +//void CSession::Decrypt(ByteArray &EncryptedData, ByteArray &Data) +//{ +// init_func + +// // NON SUPPORTATO DALLA CIE +// throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); + +/*if (pDecryptMechanism == nullptr) + throw p11_error(CKR_OPERATION_NOT_INITIALIZED); + +bool bFound = pDecryptMechanism->checkCache(EncryptedData, Data); + +if (bFound) { + pDecryptMechanism.reset(); + return; +} + +DecryptUpdate(EncryptedData, Data); +DecryptFinal(Data); + +if (Data.isNull()) + pDecryptMechanism->cacheData = EncryptedData;*/ +//} + +//void CSession::DecryptUpdate(ByteArray &EncryptedData, ByteArray &Data) +//{ +// init_func + +// // NON SUPPORTATO DALLA CIE +// throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); + +/*if (pDecryptMechanism == nullptr) + throw p11_error(CKR_OPERATION_NOT_INITIALIZED); + +ByteDynArray baData = pDecryptMechanism->DecryptUpdate(EncryptedData); + +if (!Data.isNull() && Data.size() < baData.size()) + throw p11_error(CKR_BUFFER_TOO_SMALL); +Data = Data.left(baData.size()); +if (Data.isNull()) + return; +Data.copy(baData);*/ +//} + +//void CSession::DecryptFinal(ByteArray &Data) +//{ +// init_func + +// // NON SUPPORTATO DALLA CIE +// throw p11_error(CKR_FUNCTION_NOT_SUPPORTED); + +/*if (pDecryptMechanism == nullptr) + throw p11_error(CKR_OPERATION_NOT_INITIALIZED); + +auto mech = make_resetter(pDecryptMechanism); +bool bFound = pDecryptMechanism->checkCache(ByteArray(), Data); + +if (bFound) + return; + +std::shared_ptr pObject = pSlot->GetObjectFromID(pDecryptMechanism->hDecryptKey); +if (pObject == nullptr) + throw p11_error(CKR_KEY_HANDLE_INVALID); +if (pObject->ObjClass != CKO_PRIVATE_KEY) + throw p11_error(CKR_KEY_HANDLE_INVALID); +auto pDecryptKey = std::static_pointer_cast(pObject); + +if (pDecryptKey->IsPrivate() && pSlot->User != CKU_USER) + throw p11_error(CKR_USER_NOT_LOGGED_IN); + +ByteArray *baKeyModule = pDecryptKey->getAttribute(CKA_MODULUS); +ER_ASSERT(baKeyModule != nullptr, ERR_CANT_GET_PUBKEY_MODULUS) + +size_t dwKeyLenBytes = baKeyModule->size(); + +ByteDynArray baDecryptBuffer = pDecryptMechanism->DecryptFinal(); + +ByteDynArray baData; +pSlot->pTemplate->FunctionList.templateDecrypt(pSlot->pTemplateData, pDecryptKey.get(), baDecryptBuffer, baData, pDecryptMechanism->mtType, false); + +ByteDynArray baUnpaddedData = pDecryptMechanism->DecryptRemovePadding(baData); + +if (Data.isNull()) { + pDecryptMechanism->setCache(ByteArray(), baUnpaddedData); + Data = ByteArray(nullptr, baUnpaddedData.size()); + mech.release(); +} +else if (Data.size()setCache(ByteArray(), baUnpaddedData); + Data = Data.left(baUnpaddedData.size()); + mech.release(); + throw p11_error(CKR_BUFFER_TOO_SMALL); +} +else { + pDecryptMechanism->setCache(ByteArray(), baUnpaddedData); + Data.copy(baUnpaddedData); + Data = Data.left(baUnpaddedData.size()); +}*/ +//} + +void CSession::GenerateRandom(ByteArray &RandomData) { + init_func + ByteDynArray baRandom(RandomData.size()); + pSlot->pTemplate->FunctionList.templateGenerateRandom(pSlot->pTemplateData, baRandom); + RandomData.copy(baRandom); +} + +void CSession::InitPIN(ByteArray &Pin) { + init_func + + if (pSlot->User != CKU_SO) + throw p11_error(CKR_USER_NOT_LOGGED_IN); + + pSlot->pTemplate->FunctionList.templateInitPIN(pSlot->pTemplateData, Pin); +} + +void CSession::SetPIN(ByteArray &OldPin, ByteArray &NewPin) { + init_func + + pSlot->pTemplate->FunctionList.templateSetPIN(pSlot->pTemplateData, OldPin, NewPin, pSlot->User); +} + +CK_ULONG CSession::GetObjectSize(CK_OBJECT_HANDLE hObject) { + init_func + + std::shared_ptr pObject = pSlot->GetObjectFromID(hObject); + if (pObject == nullptr) + throw p11_error(CKR_OBJECT_HANDLE_INVALID); + + + if (pObject->IsPrivate() && pSlot->User != CKU_USER) + throw p11_error(CKR_USER_NOT_LOGGED_IN); + + return pObject->GetObjectSize(); +} + +void CSession::SetAttributeValue(CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { + init_func + std::shared_ptr pObject = pSlot->GetObjectFromID(hObject); + if (pObject == nullptr) + throw p11_error(CKR_OBJECT_HANDLE_INVALID); + + if ((flags & CKF_RW_SESSION) == 0) + throw p11_error(CKR_SESSION_READ_ONLY); + + if (pSlot->User != CKU_USER) + throw p11_error(CKR_USER_NOT_LOGGED_IN); + + pSlot->pTemplate->FunctionList.templateSetAttribute(pSlot->pTemplateData, pObject.get(), pTemplate, ulCount); +} + +void CSession::SetOperationState(ByteArray &OperationState) { + init_func + CTLV Tlv(OperationState); + + ByteArray Flags, User; + Flags = Tlv.getValue(OS_Flags); + if (Flags.isNull()) throw p11_error(CKR_SAVED_STATE_INVALID); + User = Tlv.getValue(OS_User); + if (User.isNull()) + throw p11_error(CKR_SAVED_STATE_INVALID); + + if (Flags != VarToByteArray(flags)) + throw p11_error(CKR_SAVED_STATE_INVALID); + if (User != VarToByteArray(pSlot->User)) + throw p11_error(CKR_SAVED_STATE_INVALID); + + ByteArray SignOperationState = Tlv.getValue(OS_Sign); + if (!SignOperationState.isNull()) { + pSignMechanism.reset(); + CTLV SignTlv(SignOperationState); + ByteArray Algo = SignTlv.getValue(OS_Algo); + if (Algo.isNull()) + throw p11_error(CKR_SAVED_STATE_INVALID); + CK_MECHANISM mech = { ByteArrayToVar(Algo, CK_MECHANISM_TYPE), NULL, 0 }; + + ByteArray Key = SignTlv.getValue(OS_Key); + if (Key.isNull()) + throw p11_error(CKR_SAVED_STATE_INVALID); + + std::shared_ptr pKey = pSlot->FindP11Object(CKO_PRIVATE_KEY, CKA_ID, Key.data(), (int)Key.size()); + ER_ASSERT(pKey != nullptr, ERR_CANT_GET_OBJECT); + CK_OBJECT_HANDLE hKey = pSlot->GetIDFromObject(pKey); + + ByteArray Data = SignTlv.getValue(OS_Data); + if (Data.isNull()) + throw p11_error(CKR_SAVED_STATE_INVALID); + + SignInit(&mech, hKey); + pSignMechanism->SignSetOperationState(Data); + } + + /*ByteArray DecryptOperationState = Tlv.getValue(OS_Decrypt); + if (!DecryptOperationState.isNull()) { + pDecryptMechanism.reset(); + CTLV DecryptTlv(DecryptOperationState); + ByteArray Algo = DecryptTlv.getValue(OS_Algo); + throw p11_error(CKR_SAVED_STATE_INVALID); + CK_MECHANISM mech = { ByteArrayToVar(Algo, CK_MECHANISM_TYPE), NULL, 0 }; + + ByteArray Key = DecryptTlv.getValue(OS_Key); + if (Key.isNull()) + throw p11_error(CKR_SAVED_STATE_INVALID); + + std::shared_ptr pKey = pSlot->FindP11Object(CKO_PRIVATE_KEY, CKA_ID, Key.data(), (int)Key.size()); + ER_ASSERT(pKey != nullptr, ERR_CANT_GET_OBJECT) + CK_OBJECT_HANDLE hKey = pSlot->GetIDFromObject(pKey); + + ByteArray Data = DecryptTlv.getValue(OS_Data); + if (Data.isNull()) + throw p11_error(CKR_SAVED_STATE_INVALID); + + DecryptInit(&mech, hKey); + pDecryptMechanism->DecryptSetOperationState(Data); + }*/ + + ByteArray VerifyOperationState = Tlv.getValue(OS_Verify); + if (!VerifyOperationState.isNull()) { + pVerifyMechanism.reset(); + CTLV VerifyTlv(VerifyOperationState); + ByteArray Algo = VerifyTlv.getValue(OS_Algo); + if (Algo.isNull()) + throw p11_error(CKR_SAVED_STATE_INVALID); + CK_MECHANISM mech = { ByteArrayToVar(Algo, CK_MECHANISM_TYPE), NULL, 0 }; + + ByteArray Key = VerifyTlv.getValue(OS_Key); + if (Key.isNull()) + throw p11_error(CKR_SAVED_STATE_INVALID); + + std::shared_ptr pKey = pSlot->FindP11Object(CKO_PUBLIC_KEY, CKA_ID, Key.data(), (int)Key.size()); + ER_ASSERT(pKey != nullptr, ERR_CANT_GET_OBJECT) + CK_OBJECT_HANDLE hKey = pSlot->GetIDFromObject(pKey); + + ByteArray Data = VerifyTlv.getValue(OS_Data); + if (Data.isNull()) + throw p11_error(CKR_SAVED_STATE_INVALID); + + VerifyInit(&mech, hKey); + + pVerifyMechanism->VerifySetOperationState(Data); + } + + ByteArray EncryptOperationState = Tlv.getValue(OS_Encrypt); + /*if (!EncryptOperationState.isNull()) { + pEncryptMechanism.reset(); + CTLV EncryptTlv(EncryptOperationState); + ByteArray Algo = EncryptTlv.getValue(OS_Algo); + if (Algo.isNull()) + throw p11_error(CKR_SAVED_STATE_INVALID); + CK_MECHANISM mech = { ByteArrayToVar(Algo, CK_MECHANISM_TYPE), NULL, 0 }; + + ByteArray Key = EncryptTlv.getValue(OS_Key); + if (Key.isNull()) + throw p11_error(CKR_SAVED_STATE_INVALID); + + std::shared_ptr pKey = pSlot->FindP11Object(CKO_PUBLIC_KEY, CKA_ID, Key.data(), (int)Key.size()); + ER_ASSERT(pKey != nullptr, ERR_CANT_GET_OBJECT); + CK_OBJECT_HANDLE hKey = pSlot->GetIDFromObject(pKey); + + ByteArray Data = EncryptTlv.getValue(OS_Data); + if (Data.isNull()) + throw p11_error(CKR_SAVED_STATE_INVALID); + + EncryptInit(&mech, hKey); + + pEncryptMechanism->EncryptSetOperationState(Data); + }*/ + + ByteArray DigestOperationState = Tlv.getValue(OS_Digest); + if (!DigestOperationState.isNull()) { + pDigestMechanism.reset(); + CTLV DigestTlv(DigestOperationState); + ByteArray Algo = DigestTlv.getValue(OS_Algo); + if (Algo.isNull()) + throw p11_error(CKR_SAVED_STATE_INVALID); + CK_MECHANISM mech = { ByteArrayToVar(Algo, CK_MECHANISM_TYPE), NULL, 0 }; + + ByteArray Data = DigestTlv.getValue(OS_Data); + if (Data.isNull()) + throw p11_error(CKR_SAVED_STATE_INVALID); + + DigestInit(&mech); + + pDigestMechanism->DigestSetOperationState(Data); + } +} + +void CSession::GetOperationState(ByteArray &OperationState) { + init_func + + CTLVCreate Tlv; + ByteArray ba1((BYTE*)&flags, sizeof(flags)); + Tlv.setValue(OS_Flags, ba1); + ByteArray ba2((BYTE*)&flags, sizeof(flags)); + Tlv.setValue(OS_User, ba2); + if (pSignMechanism) { + CTLVCreate SignTlv; + ByteArray ba3((BYTE*)&pSignMechanism->mtType, sizeof(pSignMechanism->mtType)); + SignTlv.setValue(OS_Algo, ba3); + ByteDynArray SignData = pSignMechanism->SignGetOperationState(); + if (!SignData.isEmpty()) + SignTlv.setValue(OS_Data, SignData); + + std::shared_ptr pKey = pSlot->GetObjectFromID(pSignMechanism->hSignKey); + ER_ASSERT(pKey != nullptr, ERR_CANT_GET_OBJECT); + ByteArray *SignKeyID = pKey->getAttribute(CKA_ID); + ER_ASSERT(SignKeyID != nullptr, ERR_CANT_FIND_ID); + SignTlv.setValue(OS_Key, *SignKeyID); + + ByteDynArray *SignOperationState = Tlv.addValue(OS_Sign); + *SignOperationState = SignTlv.getBuffer(); + } + if (pVerifyMechanism) { + CTLVCreate VerifyTlv; + ByteArray ba((BYTE*)&pVerifyMechanism->mtType, sizeof(pVerifyMechanism->mtType)); + VerifyTlv.setValue(OS_Algo, ba); + ByteDynArray verifyData = pVerifyMechanism->VerifyGetOperationState(); + if (!verifyData.isEmpty()) + VerifyTlv.setValue(OS_Data, verifyData); + + + std::shared_ptr pKey = pSlot->GetObjectFromID(pVerifyMechanism->hVerifyKey); + ER_ASSERT(pKey != nullptr, ERR_CANT_GET_OBJECT); + ByteArray *VerifyKeyID = pKey->getAttribute(CKA_ID); + ER_ASSERT(VerifyKeyID != nullptr, ERR_CANT_FIND_ID); + VerifyTlv.setValue(OS_Key, *VerifyKeyID); + + ByteDynArray *VerifyOperationState = Tlv.addValue(OS_Verify); + *VerifyOperationState = VerifyTlv.getBuffer(); + } + if (pDigestMechanism) { + CTLVCreate DigestTlv; + ByteArray ba((BYTE*)&pDigestMechanism->mtType, sizeof(pDigestMechanism->mtType)); + DigestTlv.setValue(OS_Algo, ba); + ByteDynArray DigestData = pDigestMechanism->DigestGetOperationState(); + if (!DigestData.isEmpty()) + DigestTlv.setValue(OS_Data, DigestData); + + ByteDynArray *DigestOperationState = Tlv.addValue(OS_Digest); + *DigestOperationState = DigestTlv.getBuffer(); + } + /*if (pEncryptMechanism) { + CTLVCreate EncryptTlv; + EncryptTlv.setValue(OS_Algo, ByteArray((BYTE*)&pEncryptMechanism->mtType, sizeof(pEncryptMechanism->mtType))); + ByteDynArray EncryptData = pEncryptMechanism->EncryptGetOperationState(); + if (!EncryptData.isEmpty()) + EncryptTlv.setValue(OS_Data, EncryptData); + + + std::shared_ptr pKey = pSlot->GetObjectFromID(pEncryptMechanism->hEncryptKey); + ER_ASSERT(pKey != nullptr, ERR_CANT_GET_OBJECT); + ByteArray *EncryptKeyID = pKey->getAttribute(CKA_ID); + ER_ASSERT(EncryptKeyID != nullptr, ERR_CANT_FIND_ID); + EncryptTlv.setValue(OS_Key, *EncryptKeyID); + + ByteDynArray *EncryptOperationState = Tlv.addValue(OS_Encrypt); + *EncryptOperationState = EncryptTlv.getBuffer(); + }*/ + /*if (pDecryptMechanism) { + CTLVCreate DecryptTlv; + DecryptTlv.setValue(OS_Algo, ByteArray((BYTE*)&pDecryptMechanism->mtType, sizeof(pDecryptMechanism->mtType))); + ByteDynArray DecryptData = pDecryptMechanism->DecryptGetOperationState(); + if (!DecryptData.isEmpty()) + DecryptTlv.setValue(OS_Data, DecryptData); + + + std::shared_ptr pKey = pSlot->GetObjectFromID(pDecryptMechanism->hDecryptKey); + ER_ASSERT(pKey != nullptr, ERR_CANT_GET_OBJECT); + ByteArray *DecryptKeyID = pKey->getAttribute(CKA_ID); + ER_ASSERT(DecryptKeyID != nullptr, ERR_CANT_FIND_ID); + DecryptTlv.setValue(OS_Key, *DecryptKeyID); + + ByteDynArray *DecryptOperationState = Tlv.addValue(OS_Decrypt); + *DecryptOperationState = DecryptTlv.getBuffer(); + }*/ + ByteDynArray newOperationState = Tlv.getBuffer(); + + if (newOperationState.size() == 0) + throw p11_error(CKR_OPERATION_NOT_INITIALIZED); + + if (OperationState.isNull()) { + OperationState = ByteArray(nullptr, newOperationState.size()); + return; + } + if (OperationState.size() < newOperationState.size()) + throw p11_error(CKR_BUFFER_TOO_SMALL); + + OperationState.copy(newOperationState); +} +}; diff --git a/libcie-pkcs11/Sign/CIESign.cpp b/libcie-pkcs11/Sign/CIESign.cpp index a8b30e4c..605ba957 100644 --- a/libcie-pkcs11/Sign/CIESign.cpp +++ b/libcie-pkcs11/Sign/CIESign.cpp @@ -1,131 +1,135 @@ -#include "CIESign.h" -#include "disigonsdk.h" -#include - - -CIESign::CIESign(IAS *ias) { - this->ias = ias; - -} - -uint16_t CIESign::sign(const char* inFilePath, const char* type, const char* pin, int page, float x, float y, float w, float h, const char* imagePathFile,const char* outFilePath) { - - uint16_t response; - - DISIGON_CTX ctx = NULL; - long ret = 0; - - try { - ctx = disigon_sign_init(); - -#if 0 - ret = disigon_set(DISIGON_OPT_LOG_LEVEL, (void*)LOG_TYPE_DEBUG); - if (ret != 0) { - throw ret; - } -#endif - - ret = disigon_sign_set(ctx, DISIGON_OPT_IAS_INSTANCE, (IAS*)(this->ias)); - if (ret != 0) { - throw ret; - } - ret = disigon_sign_set(ctx, DISIGON_OPT_CADES, (void*)1); - if (ret != 0) { - throw ret; - } - ret = disigon_sign_set(ctx, DISIGON_OPT_PIN, (void*)pin); - if (ret != 0) { - throw ret; - } - - ret = disigon_sign_set(ctx, DISIGON_OPT_INPUTFILE, (void*)inFilePath); - if (ret != 0) { - throw ret; - } - - ret = disigon_sign_set(ctx, DISIGON_OPT_OUTPUTFILE, (void*)outFilePath); - if (ret != 0) { - throw ret; - } - - if (strcmp(type, "pdf") == 0) { - ret = disigon_sign_set(ctx, DISIGON_OPT_PDF_SUBFILTER, (void*)DISIGON_PDF_SUBFILTER_ETSI_CADES); - if (ret != 0) { - throw ret; - } - - ret = disigon_sign_set(ctx, DISIGON_OPT_PDF_PAGE, (void*)&page); - if (ret != 0) { - throw ret; - } - - ret = disigon_sign_set(ctx, DISIGON_OPT_PDF_LEFT, (void*)&x); - if (ret != 0) { - throw ret; - } - - ret = disigon_sign_set(ctx, DISIGON_OPT_PDF_BOTTOM, (void*)&y); - if (ret != 0) { - throw ret; - } - - ret = disigon_sign_set(ctx, DISIGON_OPT_PDF_WIDTH, (void*)&w); - if (ret != 0) { - throw ret; - } - - ret = disigon_sign_set(ctx, DISIGON_OPT_PDF_HEIGHT, (void*)&h); - if (ret != 0) { - throw ret; - } - - if (imagePathFile) { - ret = disigon_sign_set(ctx, DISIGON_OPT_PDF_IMAGEPATH, (void*)imagePathFile); - if (ret != 0) { - throw ret; - } - } - - ret = disigon_sign_set(ctx, DISIGON_OPT_INPUTFILE_TYPE, (void*)DISIGON_FILETYPE_PDF); - if (ret != 0) { - throw ret; - } - } else { - - if ((strstr(inFilePath, "p7m") != NULL) || (strstr(inFilePath, "p7s") != NULL)) - ret = disigon_sign_set(ctx, DISIGON_OPT_INPUTFILE_TYPE, (void*)DISIGON_FILETYPE_P7M); - else - ret = disigon_sign_set(ctx, DISIGON_OPT_INPUTFILE_TYPE, (void*)DISIGON_FILETYPE_PLAINTEXT); - - if (ret != 0) { - throw ret; - } - - ret = disigon_sign_set(ctx, DISIGON_OPT_DETACHED, (void*)0); - if (ret != 0) { - throw ret; - } - } - - ret = disigon_sign_set(ctx, DISIGON_OPT_VERIFY_USER_CERTIFICATE, 0); - if (ret != 0) { - throw ret; - } - - - ret = disigon_sign_sign(ctx); - if (ret != 0) { - throw ret; - } - } catch (long err) { - OutputDebugString("%s", "CIESign::sign error %d", err); - } - - if (ctx) - disigon_sign_cleanup(ctx); - - response = ret; - - return response; - -} +#include "CIESign.h" +#include "disigonsdk.h" +#include +#include "../LOGGER/Logger.h" + +using namespace CieIDLogger; + + + +CIESign::CIESign(IAS *ias) { + this->ias = ias; + +} + +uint16_t CIESign::sign(const char* inFilePath, const char* type, const char* pin, int page, float x, float y, float w, float h, const char* imagePathFile,const char* outFilePath) { + + uint16_t response; + + DISIGON_CTX ctx = NULL; + long ret = 0; + + try { + ctx = disigon_sign_init(); + +#if 0 + ret = disigon_set(DISIGON_OPT_LOG_LEVEL, (void*)LOG_TYPE_DEBUG); + if (ret != 0) { + throw ret; + } +#endif + + ret = disigon_sign_set(ctx, DISIGON_OPT_IAS_INSTANCE, (IAS*)(this->ias)); + if (ret != 0) { + throw ret; + } + ret = disigon_sign_set(ctx, DISIGON_OPT_CADES, (void*)1); + if (ret != 0) { + throw ret; + } + ret = disigon_sign_set(ctx, DISIGON_OPT_PIN, (void*)pin); + if (ret != 0) { + throw ret; + } + + ret = disigon_sign_set(ctx, DISIGON_OPT_INPUTFILE, (void*)inFilePath); + if (ret != 0) { + throw ret; + } + + ret = disigon_sign_set(ctx, DISIGON_OPT_OUTPUTFILE, (void*)outFilePath); + if (ret != 0) { + throw ret; + } + + if (strcmp(type, "pdf") == 0) { + ret = disigon_sign_set(ctx, DISIGON_OPT_PDF_SUBFILTER, (void*)DISIGON_PDF_SUBFILTER_ETSI_CADES); + if (ret != 0) { + throw ret; + } + + ret = disigon_sign_set(ctx, DISIGON_OPT_PDF_PAGE, (void*)&page); + if (ret != 0) { + throw ret; + } + + ret = disigon_sign_set(ctx, DISIGON_OPT_PDF_LEFT, (void*)&x); + if (ret != 0) { + throw ret; + } + + ret = disigon_sign_set(ctx, DISIGON_OPT_PDF_BOTTOM, (void*)&y); + if (ret != 0) { + throw ret; + } + + ret = disigon_sign_set(ctx, DISIGON_OPT_PDF_WIDTH, (void*)&w); + if (ret != 0) { + throw ret; + } + + ret = disigon_sign_set(ctx, DISIGON_OPT_PDF_HEIGHT, (void*)&h); + if (ret != 0) { + throw ret; + } + + if (imagePathFile) { + ret = disigon_sign_set(ctx, DISIGON_OPT_PDF_IMAGEPATH, (void*)imagePathFile); + if (ret != 0) { + throw ret; + } + } + + ret = disigon_sign_set(ctx, DISIGON_OPT_INPUTFILE_TYPE, (void*)DISIGON_FILETYPE_PDF); + if (ret != 0) { + throw ret; + } + } else { + + if ((strstr(inFilePath, "p7m") != NULL) || (strstr(inFilePath, "p7s") != NULL)) + ret = disigon_sign_set(ctx, DISIGON_OPT_INPUTFILE_TYPE, (void*)DISIGON_FILETYPE_P7M); + else + ret = disigon_sign_set(ctx, DISIGON_OPT_INPUTFILE_TYPE, (void*)DISIGON_FILETYPE_PLAINTEXT); + + if (ret != 0) { + throw ret; + } + + ret = disigon_sign_set(ctx, DISIGON_OPT_DETACHED, (void*)0); + if (ret != 0) { + throw ret; + } + } + + ret = disigon_sign_set(ctx, DISIGON_OPT_VERIFY_USER_CERTIFICATE, 0); + if (ret != 0) { + throw ret; + } + + + ret = disigon_sign_sign(ctx); + if (ret != 0) { + throw ret; + } + } catch (long err) { + LOG_ERROR("CIESign::sign error %d", err); + } + + if (ctx) + disigon_sign_cleanup(ctx); + + response = ret; + + return response; + +} diff --git a/libcie-pkcs11/Sign/CIEVerify.cpp b/libcie-pkcs11/Sign/CIEVerify.cpp index 09a76839..9daef554 100644 --- a/libcie-pkcs11/Sign/CIEVerify.cpp +++ b/libcie-pkcs11/Sign/CIEVerify.cpp @@ -1,126 +1,127 @@ -#include "CIEVerify.h" -#include "../Util/util.h" -extern CLog log; - -CIEVerify::CIEVerify() { - -} - -long CIEVerify::verify(const char* input_file, VERIFY_RESULT* verifyResult, const char* proxy_address, int proxy_port, const char* userPass) { - - try { - - DISIGON_CTX ctx; - - long ret; - ctx = disigon_verify_init(); - -#if 0 - - ret = disigon_set(DISIGON_OPT_LOG_LEVEL, (void*)LOG_TYPE_DEBUG); -#endif - - ret = disigon_verify_set(ctx, DISIGON_OPT_INPUTFILE, (void*)input_file); - if (ret != 0) { - throw ret; - } - - ret = disigon_verify_set(ctx, DISIGON_OPT_INPUTFILE_TYPE, (void*)DISIGON_FILETYPE_AUTO); - if (ret != 0) { - throw ret; - } - - //ret = disigon_verify_set(ctx, DISIGON_OPT_INPUTFILE_PLAINTEXT, "input-restored.txt"); - - //PARAMETRO 0 non usa verifica OCSP - //PARAMETRO 1 OK OCSP - ret = disigon_verify_set(ctx, DISIGON_OPT_VERIFY_REVOCATION, (void*)1); - if (ret != 0) { - throw ret; - } - - - if (proxy_address) { - ret = disigon_verify_set(ctx, DISIGON_OPT_PROXY, (void*)proxy_address); - if (ret != 0) { - throw ret; - } - - if (proxy_port == 0) { - OutputDebugString("%s", "CIEVerify::invalid proxy port"); - return DISIGON_ERROR_INVALID_SIGOPT; - } else { - ret = disigon_verify_set(ctx, DISIGON_OPT_PROXY_PORT, (void*)proxy_port); - if (ret != 0) { - throw ret; - } - - if (userPass) { - ret = disigon_verify_set(ctx, DISIGON_OPT_PROXY_USRPASS, (void*)userPass); - if (ret != 0) { - throw ret; - } - } - - } - - } - - ret = disigon_verify_verify(ctx, verifyResult); - if (ret != 0) { - throw ret; - } - - ret = disigon_verify_cleanup(ctx); - if (ret != 0) { - throw ret; - } - - - return ret; - - } catch (long err) { - OutputDebugString("%s", "CIEVerify::verify error: %lx", err); - } -} - -long CIEVerify::get_file_from_p7m(const char* input_file, const char* output_file) { - - try { - DISIGON_CTX ctx; - - long ret; - ctx = disigon_verify_init(); - -#if 1 - - ret = disigon_set(DISIGON_OPT_LOG_LEVEL, (void*)LOG_TYPE_DEBUG); -#endif - - ret = disigon_verify_set(ctx, DISIGON_OPT_INPUTFILE, (void*)input_file); - if (ret != 0) { - throw ret; - } - - ret = disigon_verify_set(ctx, DISIGON_OPT_INPUTFILE_TYPE, (void*)DISIGON_FILETYPE_AUTO); - if (ret != 0) { - throw ret; - } - - ret = disigon_verify_set(ctx, DISIGON_OPT_OUTPUTFILE, (void*)output_file); - if (ret != 0) { - throw ret; - } - - ret = disigon_get_file_from_p7m(ctx); - if (ret != 0) { - throw ret; - } - - return ret; - } catch (long err) { - OutputDebugString("%s", "CIEVerify::verify error: %lx", err); - return err; - } - -} +#include "CIEVerify.h" +#include "../LOGGER/Logger.h" + +using namespace CieIDLogger; + +CIEVerify::CIEVerify() { + +} + +long CIEVerify::verify(const char* input_file, VERIFY_RESULT* verifyResult, const char* proxy_address, int proxy_port, const char* userPass) { + + try { + + DISIGON_CTX ctx; + + long ret; + ctx = disigon_verify_init(); + +#if 1 + + ret = disigon_set(DISIGON_OPT_LOG_LEVEL, (void*)LOG_TYPE_DEBUG); +#endif + + ret = disigon_verify_set(ctx, DISIGON_OPT_INPUTFILE, (void*)input_file); + if (ret != 0) { + throw ret; + } + + ret = disigon_verify_set(ctx, DISIGON_OPT_INPUTFILE_TYPE, (void*)DISIGON_FILETYPE_AUTO); + if (ret != 0) { + throw ret; + } + + //ret = disigon_verify_set(ctx, DISIGON_OPT_INPUTFILE_PLAINTEXT, "input-restored.txt"); + + //PARAMETRO 0 non usa verifica OCSP + //PARAMETRO 1 OK OCSP + ret = disigon_verify_set(ctx, DISIGON_OPT_VERIFY_REVOCATION, (void*)1); + if (ret != 0) { + throw ret; + } + + + if (proxy_address) { + ret = disigon_verify_set(ctx, DISIGON_OPT_PROXY, (void*)proxy_address); + if (ret != 0) { + throw ret; + } + + if (proxy_port == 0) { + LOG_ERROR("CIEVerify::invalid proxy port"); + return DISIGON_ERROR_INVALID_SIGOPT; + } else { + ret = disigon_verify_set(ctx, DISIGON_OPT_PROXY_PORT, (void*)proxy_port); + if (ret != 0) { + throw ret; + } + + if (userPass) { + ret = disigon_verify_set(ctx, DISIGON_OPT_PROXY_USRPASS, (void*)userPass); + if (ret != 0) { + throw ret; + } + } + + } + + } + + ret = disigon_verify_verify(ctx, verifyResult); + if (ret != 0) { + throw ret; + } + + ret = disigon_verify_cleanup(ctx); + if (ret != 0) { + throw ret; + } + + + return ret; + + } catch (long err) { + LOG_ERROR("CIEVerify::verify error: %lx", err); + } +} + +long CIEVerify::get_file_from_p7m(const char* input_file, const char* output_file) { + + try { + DISIGON_CTX ctx; + + long ret; + ctx = disigon_verify_init(); + +#if 1 + + ret = disigon_set(DISIGON_OPT_LOG_LEVEL, (void*)LOG_TYPE_DEBUG); +#endif + + ret = disigon_verify_set(ctx, DISIGON_OPT_INPUTFILE, (void*)input_file); + if (ret != 0) { + throw ret; + } + + ret = disigon_verify_set(ctx, DISIGON_OPT_INPUTFILE_TYPE, (void*)DISIGON_FILETYPE_AUTO); + if (ret != 0) { + throw ret; + } + + ret = disigon_verify_set(ctx, DISIGON_OPT_OUTPUTFILE, (void*)output_file); + if (ret != 0) { + throw ret; + } + + ret = disigon_get_file_from_p7m(ctx); + if (ret != 0) { + throw ret; + } + + return ret; + } catch (long err) { + LOG_ERROR("CIEVerify::verify error: %lx", err); + return err; + } + +} diff --git a/libcie-pkcs11/Util/Array.cpp b/libcie-pkcs11/Util/Array.cpp index 940b3cea..52b7f4ea 100644 --- a/libcie-pkcs11/Util/Array.cpp +++ b/libcie-pkcs11/Util/Array.cpp @@ -1,347 +1,347 @@ -#include "Array.h" -#include -#include -#include -#include -#include -#include -//#include -//#include - - -ByteArray::ByteArray() { - _data = nullptr; - _size = 0; -} - -ByteArray::ByteArray(uint8_t* data, size_t size) { - _data = data; - _size = size; -} - -ByteDynArray::ByteDynArray(ByteDynArray &&src) { - _data = src._data; - _size = src._size; - src._data = nullptr; - src._size = 0; -} - -ByteArray::ByteArray(const ByteArray& ba, size_t start) { - if (start>ba.size()) - throw logged_error("Array derivato troppo grande"); - - _size = ba.size() - start; - _data = ba._data + start; - -// _data = new uint8_t[_size]; -// copy(ba, start); -} - -ByteArray::ByteArray(const ByteArray& ba, size_t start, size_t size) { - if (start + size>ba.size()) - throw logged_error("Array derivato troppo grande"); - _size = size; - _data = ba._data + start; -// _data = new uint8_t[_size]; -// copy(ba, start); -} - -ByteArray::ByteArray(const ByteArray &src) { - _size = src._size; - _data = src._data; -// _data = new uint8_t[_size]; -// copy(src); -}; - -ByteDynArray &ByteDynArray::operator = (ByteDynArray &&src) { - _data = src._data; - _size = src._size; - src._data = nullptr; - src._size = 0; - return *this; -} - -bool ByteArray::operator==(const ByteArray &src) const { - if (_size != src._size) - return false; - return (memcmp(_data, src._data, _size) == 0); - -}; - -int ByteArray::atoi() const { - int val = 0; - for (size_t i = 0; i<_size; i++) { - if (val>(INT_MAX / 10)) - throw std::overflow_error("owerflow"); - val = (val * 10) + _data[i] - '0'; - } - return val; -} -bool ByteArray::operator<(const ByteArray &src) const { - if (_size(const ByteArray &src) const { - - if (_size>src._size) - return true; - return (memcmp(_data, src._data, _size)>0); -}; - -bool ByteArray::operator!=(const ByteArray &src) const { - if (_size != src._size) - return true; - return (memcmp(_data, src._data, _size) != 0); -}; - -void ByteArray::copy(const ByteArray &src, size_t start) { - if (src._size + start>_size) - throw logged_error(stdPrintf("Dimensione array da copiare %i troppo grande; dimensione massima %i", src._size + start, _size)); - if(src._size > 0 && src._data) - CryptoPP::memcpy_s(_data + start, _size - (start), src._data, src._size); -} - -void ByteArray::rightcopy(const ByteArray &src, size_t end) { - if (src._size + end>_size) - throw logged_error(stdPrintf("Dimensione array da copiare %i troppo grande; dimensione massima %i", src._size + end, _size)); - CryptoPP::memcpy_s(_data + _size - end - src._size, (end + src._size), src._data, src._size); -} - -ByteArray &ByteArray::fill(const uint8_t value) { - for (size_t i = 0; i<_size; i++) - _data[i] = value; - return *this; -} - -#ifdef WIN32 -class init_rnd { - public: - BCRYPT_ALG_HANDLE algo; - init_rnd() { - if (BCryptOpenAlgorithmProvider(&algo, BCRYPT_RNG_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0) != 0) - throw logged_error("Errore nell'inizializzazione dell'algoritmo Random"); - } - ~init_rnd() { - BCryptCloseAlgorithmProvider(algo, 0); - } -} algo_rnd; - -ByteArray &ByteArray::random() { - BCryptGenRandom(algo_rnd.algo, _data, (ULONG)_size, 0); - return *this; -} -#else -class init_rnd { - public: - init_rnd() { -// SYSTEMTIME tm; -// GetSystemTime(&tm); -// RAND_seed(&tm, sizeof(SYSTEMTIME)); - } -} _initRand; - -ByteArray &ByteArray::random() { - RAND_bytes(_data, (int)_size); -// CryptoPP::SecByteBlock key(_size); -// CryptoPP::OS_GenerateRandomBlock(true, key, key.size()); -// memcpy(_data, key.BytePtr(), _size); -// -// _data[0] &= 0x7F; - - return *this; -} -#endif - -ByteArray &ByteArray::reverse() { - size_t dwHalfSize = _size >> 1; - uint8_t temp; - for (size_t i = 0; i_size) - throw logged_error("Array derivato troppo grande"); - return(ByteArray(*this, _size - size, size )); - -} - -ByteArray ByteArray::left(size_t size) const { - - if (size>_size) - throw logged_error("Array derivato troppo grande"); - return(ByteArray(*this, 0, size)); - -} - -ByteArray ByteArray::mid(size_t start) const { - if (start >_size) - throw logged_error("Array derivato troppo grande"); - return(ByteArray(*this, start, _size - start)); -} - -ByteArray ByteArray::mid(size_t start, size_t size) const { - if (start + size>_size) - throw logged_error("Array derivato troppo grande"); - return(ByteArray(*this, start, size )); -} - -ByteArray ByteArray::revmid(size_t toend) const { - if (toend >_size) - throw logged_error("Array derivato troppo grande"); - return(ByteArray(*this, 0, _size - toend)); -} - -ByteArray ByteArray::revmid(size_t toend, size_t size) const { - if (toend + size>_size) - throw logged_error("Array derivato troppo grande"); - return(ByteArray(*this, _size - toend - size, size )); -} - -ByteArray::~ByteArray() { - _size = 0; - _data = nullptr; -} - -ByteDynArray ByteArray::getASN1Tag(unsigned int tag) const { - - size_t tl = ASN1TLength(tag); - size_t ll = ASN1LLength(size()); - ByteDynArray result(tl + ll + size()); - putASN1Tag(tag, result); - ByteArray input(result.mid(tl)); - putASN1Length(size(), input); - result.mid(tl + ll).copy(*this); - return result; -} - -void ByteDynArray::alloc_copy(const ByteArray &src) { - clear(); - _data = new uint8_t[src.size()]; - _size = src.size(); - copy(src); - return; -} - -ByteDynArray::ByteDynArray() { - _size = 0; - _data = nullptr; -}; - -ByteDynArray::ByteDynArray(const ByteDynArray &src) : ByteDynArray() { - alloc_copy(src); -}; - -ByteDynArray::ByteDynArray(const ByteArray &src) : ByteDynArray() { - alloc_copy(src); -}; - -ByteDynArray::ByteDynArray(const std::string &hexdata) : ByteDynArray() { - readHexData(hexdata, *this); -} - -ByteDynArray::ByteDynArray(size_t size) { - _data = new uint8_t[size]; - _size = size; - -}; -ByteDynArray::~ByteDynArray() { - clear(); -} - -ByteDynArray &ByteDynArray::operator = (const ByteDynArray &src) { - alloc_copy(src); - return *this; -} - -void ByteDynArray::resize(size_t size, bool bKeepData) { - if (!bKeepData) { - clear(); - _data = new uint8_t[size]; - _size = size; - } else { - uint8_t* pbtNewData = new uint8_t[size]; - size_t dwMinSize = std::min(size, _size); - if (dwMinSize>0) - CryptoPP::memcpy_s(pbtNewData, size, _data, dwMinSize); - clear(); - _data = pbtNewData; - _size = size; - } -} - -void ByteDynArray::clear() { - if (_data != nullptr) - delete[] _data; - _data = nullptr; - _size = 0; -} - -ByteDynArray &ByteDynArray::append(const ByteArray &src) { - if (src.size()>0) { - resize(_size + src.size(), true); - rightcopy(src); - } - return *this; -} - -ByteDynArray &ByteDynArray::push(const uint8_t data) { - resize(_size + 1, true); - _data[_size - 1] = data; - return *this; -} - -uint8_t* ByteDynArray::detach() { - uint8_t* data = _data; - _data = nullptr; - _size = 0; - - return data; -} -bool ByteArray::indexOf(ByteArray &data,size_t &position) const { - if (data.size() == 0) - return 0; - if (_size < data.size()) - return false; - size_t start = _size - data.size(); - for (size_t i = 0; i <= start; i++) { - bool ok = true; - for (unsigned int j = 0; j < data.size(); j++) { - if (_data[i + j] != data[j]) { - ok = false; - break; - } - } - if (ok) { - position = i; - return true; - } - } - return false; -} - -ByteDynArray &ByteDynArray::setASN1Tag(unsigned int tag, ByteArray& content) { - size_t tl = ASN1TLength(tag); - size_t ll = ASN1LLength(content.size()); - resize(tl + ll + content.size()); - putASN1Tag(tag, *this); - ByteArray input = mid(tl); - putASN1Length(content.size(), input); - mid(tl + ll).copy(content); - return *this; -} -void ByteDynArray::load(const char *fname) { - std::ifstream file(fname,std::ios::in | std::ios::binary); - file.seekg(0, file.end); - auto fsize = file.tellg(); - file.seekg(0, file.beg); - resize((size_t)fsize, false); - file.read((char*)_data, fsize); -} +#include "Array.h" +#include +#include +#include +#include +#include +#include +//#include +//#include + + +ByteArray::ByteArray() { + _data = nullptr; + _size = 0; +} + +ByteArray::ByteArray(uint8_t* data, size_t size) { + _data = data; + _size = size; +} + +ByteDynArray::ByteDynArray(ByteDynArray &&src) { + _data = src._data; + _size = src._size; + src._data = nullptr; + src._size = 0; +} + +ByteArray::ByteArray(const ByteArray& ba, size_t start) { + if (start>ba.size()) + throw logged_error("Array derivato troppo grande"); + + _size = ba.size() - start; + _data = ba._data + start; + +// _data = new uint8_t[_size]; +// copy(ba, start); +} + +ByteArray::ByteArray(const ByteArray& ba, size_t start, size_t size) { + if (start + size>ba.size()) + throw logged_error("Array derivato troppo grande"); + _size = size; + _data = ba._data + start; +// _data = new uint8_t[_size]; +// copy(ba, start); +} + +ByteArray::ByteArray(const ByteArray &src) { + _size = src._size; + _data = src._data; +// _data = new uint8_t[_size]; +// copy(src); +}; + +ByteDynArray &ByteDynArray::operator = (ByteDynArray &&src) { + _data = src._data; + _size = src._size; + src._data = nullptr; + src._size = 0; + return *this; +} + +bool ByteArray::operator==(const ByteArray &src) const { + if (_size != src._size) + return false; + return (memcmp(_data, src._data, _size) == 0); + +}; + +int ByteArray::atoi() const { + int val = 0; + for (size_t i = 0; i<_size; i++) { + if (val>(INT_MAX / 10)) + throw std::overflow_error("owerflow"); + val = (val * 10) + _data[i] - '0'; + } + return val; +} +bool ByteArray::operator<(const ByteArray &src) const { + if (_size(const ByteArray &src) const { + + if (_size>src._size) + return true; + return (memcmp(_data, src._data, _size)>0); +}; + +bool ByteArray::operator!=(const ByteArray &src) const { + if (_size != src._size) + return true; + return (memcmp(_data, src._data, _size) != 0); +}; + +void ByteArray::copy(const ByteArray &src, size_t start) { + if (src._size + start>_size) + throw logged_error(stdPrintf("Dimensione array da copiare %i troppo grande; dimensione massima %i", src._size + start, _size)); + if(src._size > 0 && src._data) + CryptoPP::memcpy_s(_data + start, _size - (start), src._data, src._size); +} + +void ByteArray::rightcopy(const ByteArray &src, size_t end) { + if (src._size + end>_size) + throw logged_error(stdPrintf("Dimensione array da copiare %i troppo grande; dimensione massima %i", src._size + end, _size)); + CryptoPP::memcpy_s(_data + _size - end - src._size, (end + src._size), src._data, src._size); +} + +ByteArray &ByteArray::fill(const uint8_t value) { + for (size_t i = 0; i<_size; i++) + _data[i] = value; + return *this; +} + +#ifdef WIN32 +class init_rnd { + public: + BCRYPT_ALG_HANDLE algo; + init_rnd() { + if (BCryptOpenAlgorithmProvider(&algo, BCRYPT_RNG_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0) != 0) + throw logged_error("Errore nell'inizializzazione dell'algoritmo Random"); + } + ~init_rnd() { + BCryptCloseAlgorithmProvider(algo, 0); + } +} algo_rnd; + +ByteArray &ByteArray::random() { + BCryptGenRandom(algo_rnd.algo, _data, (ULONG)_size, 0); + return *this; +} +#else +class init_rnd { + public: + init_rnd() { +// SYSTEMTIME tm; +// GetSystemTime(&tm); +// RAND_seed(&tm, sizeof(SYSTEMTIME)); + } +} _initRand; + +ByteArray &ByteArray::random() { + RAND_bytes(_data, (int)_size); +// CryptoPP::SecByteBlock key(_size); +// CryptoPP::OS_GenerateRandomBlock(true, key, key.size()); +// memcpy(_data, key.BytePtr(), _size); +// +// _data[0] &= 0x7F; + + return *this; +} +#endif + +ByteArray &ByteArray::reverse() { + size_t dwHalfSize = _size >> 1; + uint8_t temp; + for (size_t i = 0; i_size) + throw logged_error("Array derivato troppo grande"); + return(ByteArray(*this, _size - size, size )); + +} + +ByteArray ByteArray::left(size_t size) const { + + if (size>_size) + throw logged_error("Array derivato troppo grande"); + return(ByteArray(*this, 0, size)); + +} + +ByteArray ByteArray::mid(size_t start) const { + if (start >_size) + throw logged_error("Array derivato troppo grande"); + return(ByteArray(*this, start, _size - start)); +} + +ByteArray ByteArray::mid(size_t start, size_t size) const { + if (start + size>_size) + throw logged_error("Array derivato troppo grande"); + return(ByteArray(*this, start, size )); +} + +ByteArray ByteArray::revmid(size_t toend) const { + if (toend >_size) + throw logged_error("Array derivato troppo grande"); + return(ByteArray(*this, 0, _size - toend)); +} + +ByteArray ByteArray::revmid(size_t toend, size_t size) const { + if (toend + size>_size) + throw logged_error("Array derivato troppo grande"); + return(ByteArray(*this, _size - toend - size, size )); +} + +ByteArray::~ByteArray() { + _size = 0; + _data = nullptr; +} + +ByteDynArray ByteArray::getASN1Tag(unsigned int tag) const { + + size_t tl = ASN1TLength(tag); + size_t ll = ASN1LLength(size()); + ByteDynArray result(tl + ll + size()); + putASN1Tag(tag, result); + ByteArray input(result.mid(tl)); + putASN1Length(size(), input); + result.mid(tl + ll).copy(*this); + return result; +} + +void ByteDynArray::alloc_copy(const ByteArray &src) { + clear(); + _data = new uint8_t[src.size()]; + _size = src.size(); + copy(src); + return; +} + +ByteDynArray::ByteDynArray() { + _size = 0; + _data = nullptr; +}; + +ByteDynArray::ByteDynArray(const ByteDynArray &src) : ByteDynArray() { + alloc_copy(src); +}; + +ByteDynArray::ByteDynArray(const ByteArray &src) : ByteDynArray() { + alloc_copy(src); +}; + +ByteDynArray::ByteDynArray(const std::string &hexdata) : ByteDynArray() { + readHexData(hexdata, *this); +} + +ByteDynArray::ByteDynArray(size_t size) { + _data = new uint8_t[size]; + _size = size; + +}; +ByteDynArray::~ByteDynArray() { + clear(); +} + +ByteDynArray &ByteDynArray::operator = (const ByteDynArray &src) { + alloc_copy(src); + return *this; +} + +void ByteDynArray::resize(size_t size, bool bKeepData) { + if (!bKeepData) { + clear(); + _data = new uint8_t[size]; + _size = size; + } else { + uint8_t* pbtNewData = new uint8_t[size]; + size_t dwMinSize = std::min(size, _size); + if (dwMinSize>0) + CryptoPP::memcpy_s(pbtNewData, size, _data, dwMinSize); + clear(); + _data = pbtNewData; + _size = size; + } +} + +void ByteDynArray::clear() { + if (_data != nullptr) + delete[] _data; + _data = nullptr; + _size = 0; +} + +ByteDynArray &ByteDynArray::append(const ByteArray &src) { + if (src.size()>0) { + resize(_size + src.size(), true); + rightcopy(src); + } + return *this; +} + +ByteDynArray &ByteDynArray::push(const uint8_t data) { + resize(_size + 1, true); + _data[_size - 1] = data; + return *this; +} + +uint8_t* ByteDynArray::detach() { + uint8_t* data = _data; + _data = nullptr; + _size = 0; + + return data; +} +bool ByteArray::indexOf(ByteArray &data,size_t &position) const { + if (data.size() == 0) + return 0; + if (_size < data.size()) + return false; + size_t start = _size - data.size(); + for (size_t i = 0; i <= start; i++) { + bool ok = true; + for (unsigned int j = 0; j < data.size(); j++) { + if (_data[i + j] != data[j]) { + ok = false; + break; + } + } + if (ok) { + position = i; + return true; + } + } + return false; +} + +ByteDynArray &ByteDynArray::setASN1Tag(unsigned int tag, ByteArray& content) { + size_t tl = ASN1TLength(tag); + size_t ll = ASN1LLength(content.size()); + resize(tl + ll + content.size()); + putASN1Tag(tag, *this); + ByteArray input = mid(tl); + putASN1Length(content.size(), input); + mid(tl + ll).copy(content); + return *this; +} +void ByteDynArray::load(const char *fname) { + std::ifstream file(fname,std::ios::in | std::ios::binary); + file.seekg(0, file.end); + auto fsize = file.tellg(); + file.seekg(0, file.beg); + resize((size_t)fsize, false); + file.read((char*)_data, fsize); +} diff --git a/libcie-pkcs11/Util/Array.h b/libcie-pkcs11/Util/Array.h index ac7d89c6..a6db49e6 100644 --- a/libcie-pkcs11/Util/Array.h +++ b/libcie-pkcs11/Util/Array.h @@ -143,8 +143,6 @@ class ByteDynArray : public ByteArray { buffer = buffer.mid(internalSet(&buffer, std::forward(arg0))); int dummy2[] = { 0, ((void)(buffer = buffer.mid(internalSet(&buffer, std::forward(args)))), 0) ... }; - (void)dummy; - (void)dummy2; return *this; } diff --git a/libcie-pkcs11/Util/CacheLib.cpp b/libcie-pkcs11/Util/CacheLib.cpp index 608a88d8..b6f11d00 100644 --- a/libcie-pkcs11/Util/CacheLib.cpp +++ b/libcie-pkcs11/Util/CacheLib.cpp @@ -1,377 +1,377 @@ - -#include "CacheLib.h" -//#include -//#include -#include -#include -#include -//#include "sddl.h" -//#include "Aclapi.h" -//#include -#include -#include "util.h" - -//#ifndef WIN32 - -#include -#include -#include -#include - -#include -#include -#include -#include "../keys.h" -#include - -#include - -using namespace CryptoPP; - -int decrypt(std::string& ciphertext, std::string& message); -//#endif - -/// Questa implementazione della cache del PIN e del certificato è fornita solo a scopo dimostrativo. Questa versione -/// NON protegge a sufficienza il PIN dell'utente, che potrebbe essere ricavato da un'applicazione malevola. Si raccomanda di -/// utilizzare, in contesti di produzione, un'implementazione che fornisca un elevato livello di sicurezza - -#ifdef WIN32 - -std::string commonData; - -std::string GetCardDir() { - - if (commonData[0] == 0) { - char szPath[MAX_PATH]; - ExpandEnvironmentStrings("%PROGRAMDATA%\\CIEPKI", szPath, MAX_PATH); - commonData = szPath; - } - return commonData; -} - -void GetCardPath(const char *PAN, char szPath[MAX_PATH]) { - auto Path=GetCardDir(); - - if (Path[Path.length()] != '\\') - Path += '\\'; - - Path += std::string(PAN); - Path += ".cache"; - - strlcpy(szPath, Path.c_str(), Path.size()); -} - -bool CacheExists(const char *PAN) { - char szPath[MAX_PATH]; - GetCardPath(PAN, szPath); - return (PathFileExists(szPath)!=FALSE); -} - -void CacheGetCertificate(const char *PAN, std::vector&certificate) { - if (PAN == nullptr) - throw logged_error("Il PAN è necessario"); - - char szPath[MAX_PATH]; - GetCardPath(PAN, szPath); - - if (PathFileExists(szPath)) { - - ByteDynArray data, Cert; - data.load(szPath); - uint8_t *ptr = data.data(); - uint32_t len = *(uint32_t*)ptr; - ptr += sizeof(uint32_t); - // salto il PIN - ptr += len; - len = *(uint32_t*)ptr; - ptr += sizeof(uint32_t); - Cert.resize(len); - Cert.copy(ByteArray(ptr, len)); - - certificate.resize(Cert.size()); - ByteArray(certificate.data(), certificate.size()).copy(Cert); - } else { - throw logged_error("CIE non abilitata"); - } -} - -void CacheGetPIN(const char *PAN, std::vector&PIN) { - if (PAN == nullptr) - throw logged_error("Il PAN è necessario"); - - char szPath[MAX_PATH]; - GetCardPath(PAN, szPath); - - if (PathFileExists(szPath)) { - ByteDynArray data, ClearPIN; - data.load(szPath); - uint8_t *ptr = data.data(); - uint32_t len = *(uint32_t*)ptr; - ptr += sizeof(uint32_t); - ClearPIN.resize(len); - ClearPIN.copy(ByteArray(ptr, len)); - - PIN.resize(ClearPIN.size()); - ByteArray(PIN.data(), PIN.size()).copy(ClearPIN); - - } else - throw logged_error("CIE non abilitata"); - -} - - - -void CacheSetData(const char *PAN, uint8_t *certificate, int certificateSize, uint8_t *FirstPIN, int FirstPINSize) { - if (PAN == nullptr) - throw logged_error("Il PAN è necessario"); - - auto szDir=GetCardDir(); - char chDir[MAX_PATH]; - strcpy_s(chDir, szDir.c_str()); - - if (!PathFileExists(chDir)) { - - //creo la directory dando l'accesso a Edge (utente Packege). - //Edge gira in low integrity quindi non potrà scrivere (enrollare) ma solo leggere il certificato - bool done = false; - CreateDirectory(chDir, nullptr); - - if (IsWindows8OrGreater()) { - PACL pOldDACL = nullptr, pNewDACL = nullptr; - PSECURITY_DESCRIPTOR pSD = nullptr; - EXPLICIT_ACCESS ea; - SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION; - - DWORD dwRes = GetNamedSecurityInfo(chDir, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldDACL, NULL, &pSD); - if (dwRes != ERROR_SUCCESS) - throw logged_error("Impossibile attivare la CIE nel processo corrente"); - - PSID TheSID = nullptr; - DWORD SidSize = SECURITY_MAX_SID_SIZE; - if (!(TheSID = LocalAlloc(LMEM_FIXED, SidSize))) { - if (pSD != NULL) - LocalFree((HLOCAL)pSD); - throw logged_error("Impossibile attivare la CIE nel processo corrente"); - } - - if (!CreateWellKnownSid(WinBuiltinAnyPackageSid, NULL, TheSID, &SidSize)) { - if (TheSID != NULL) - LocalFree((HLOCAL)TheSID); - if (pSD != NULL) - LocalFree((HLOCAL)pSD); - throw logged_error("Impossibile attivare la CIE nel processo corrente"); - } - - ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS)); - ea.grfAccessPermissions = GENERIC_READ; - ea.grfAccessMode = SET_ACCESS; - ea.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT; - ea.Trustee.TrusteeForm = TRUSTEE_IS_SID; - ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; - ea.Trustee.ptstrName = (LPSTR)TheSID; - - if (SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL) != ERROR_SUCCESS) { - if (TheSID != NULL) - LocalFree((HLOCAL)TheSID); - if (pSD != NULL) - LocalFree((HLOCAL)pSD); - if (pNewDACL != NULL) - LocalFree((HLOCAL)pNewDACL); - throw logged_error("Impossibile attivare la CIE nel processo corrente"); - } - - if (SetNamedSecurityInfo(chDir, SE_FILE_OBJECT, si, NULL, NULL, pNewDACL, NULL) != ERROR_SUCCESS) { - if (pNewDACL != NULL) - LocalFree((HLOCAL)pNewDACL); - if (TheSID != NULL) - LocalFree((HLOCAL)TheSID); - if (pSD != NULL) - LocalFree((HLOCAL)pSD); - throw logged_error("Impossibile attivare la CIE nel processo corrente"); - } - - } - } - char szPath[MAX_PATH]; - GetCardPath(PAN, szPath); - - ByteArray baCertificate(certificate, certificateSize); - ByteArray baFirstPIN(FirstPIN, FirstPINSize); - - std::ofstream file(szPath, std::ofstream::out | std::ofstream::binary); - - uint32_t len = (uint32_t)baFirstPIN.size(); - file.write((char*)&len, sizeof(len)); - file.write((char*)baFirstPIN.data(), len); - - len = (uint32_t)baCertificate.size(); - file.write((char*)&len, sizeof(len)); - file.write((char*)baCertificate.data(), len); -} - -#else - -bool file_exists (const char* name) { - struct stat buffer; - return (stat (name, &buffer) == 0); -} - -std::string GetCardDir() { - char* home = getenv("HOME"); - if(home == NULL) { - struct passwd *pw = getpwuid(getuid()); - - home = pw->pw_dir; - printf("home: %s", home); - } - - std::string path(home); - - path.append("/.CIEPKI/"); - - printf("Card Dir: %s\n", path.c_str()); - - return path.c_str(); -} - -void GetCardPath(const char *PAN, std::string& sPath) { - auto Path=GetCardDir(); - - Path += std::string(PAN); - Path += ".cache"; - sPath = Path; -} - -bool CacheExists(const char *PAN) { - std::string sPath; - GetCardPath(PAN, sPath); - return file_exists(sPath.c_str()); -} - -bool CacheRemove(const char *PAN) { - std::string sPath; - GetCardPath(PAN, sPath); - return remove(sPath.c_str()); -} - -void CacheGetCertificate(const char *PAN, std::vector&certificate) { - if (PAN == nullptr) - throw logged_error("Il PAN è necessario"); - - std::string sPath; - GetCardPath(PAN, sPath); - - if (file_exists(sPath.c_str())) { - - ByteDynArray data, Cert; - data.load(sPath.c_str()); - - std::string ciphertext((char*)data.data(), data.size()); - std::string plaintext; - - decrypt(ciphertext, plaintext); - - uint8_t *ptr = (uint8_t *)plaintext.c_str(); - - uint32_t len = *(uint32_t*)ptr; - ptr += sizeof(uint32_t); - // salto il PIN - ptr += len; - len = *(uint32_t*)ptr; - ptr += sizeof(uint32_t); - Cert.resize(len); - Cert.copy(ByteArray(ptr, len)); - - certificate.resize(Cert.size()); - ByteArray(certificate.data(), certificate.size()).copy(Cert); - } else { - throw logged_error("CIE non abilitata"); - } -} - -void CacheGetPIN(const char *PAN, std::vector&PIN) { - if (PAN == nullptr) - throw logged_error("Il PAN è necessario"); - - std::string sPath; - GetCardPath(PAN, sPath); - - if (file_exists(sPath.c_str())) { - ByteDynArray data, ClearPIN; - data.load(sPath.c_str()); - - std::string ciphertext((char*)data.data(), data.size()); - std::string plaintext; - - decrypt(ciphertext, plaintext); - - uint8_t *ptr = (uint8_t *)plaintext.c_str(); - uint32_t len = *(uint32_t*)ptr; - ptr += sizeof(uint32_t); - ClearPIN.resize(len); - ClearPIN.copy(ByteArray(ptr, len)); - - PIN.resize(ClearPIN.size()); - ByteArray(PIN.data(), PIN.size()).copy(ClearPIN); - - } else - throw logged_error("CIE non abilitata"); - -} - - - -void CacheSetData(const char *PAN, uint8_t *certificate, int certificateSize, uint8_t *FirstPIN, int FirstPINSize) { - if (PAN == nullptr) - throw logged_error("Il PAN è necessario"); - - auto szDir = GetCardDir(); - - struct stat st = {0}; - - if (stat(szDir.c_str(), &st) == -1) { - int r = mkdir(szDir.c_str(), 0700); - printf("mkdir: %d, %x\n", r, errno); - } - - std::string sPath; - GetCardPath(PAN, sPath); - - ByteArray baCertificate(certificate, certificateSize); - ByteArray baFirstPIN(FirstPIN, FirstPINSize); - - uint32_t pinlen = (uint32_t)baFirstPIN.size(); - uint32_t certlen = (uint32_t)baCertificate.size(); - - byte key[ CryptoPP::AES::DEFAULT_KEYLENGTH ], iv[ CryptoPP::AES::BLOCKSIZE ]; - memset( key, 0x00, CryptoPP::AES::DEFAULT_KEYLENGTH ); - memset( iv, 0x00, CryptoPP::AES::BLOCKSIZE ); - - std::string ciphertext; - std::string enckey = ENCRYPTION_KEY; - - byte digest[SHA1::DIGESTSIZE]; - SHA1().CalculateDigest(digest, (byte*)enckey.c_str(), enckey.length()); - memcpy(key, digest, CryptoPP::AES::DEFAULT_KEYLENGTH ); - // - // Create Cipher Text - // - CryptoPP::AES::Encryption aesEncryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH); - CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption( aesEncryption, iv ); - - CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::StringSink( ciphertext ) ); - stfEncryptor.Put( reinterpret_cast(&pinlen), sizeof(pinlen)); - stfEncryptor.Put( reinterpret_cast( baFirstPIN.data() ), pinlen ); - - stfEncryptor.Put( reinterpret_cast(&certlen), sizeof(certlen)); - stfEncryptor.Put( reinterpret_cast( baCertificate.data() ), certlen ); - - stfEncryptor.MessageEnd(); - - - std::ofstream file(sPath.c_str(), std::ofstream::out | std::ofstream::binary); - file.write(ciphertext.c_str(), ciphertext.length()); - file.close(); -} - -#endif + +#include "CacheLib.h" +//#include +//#include +#include +#include +#include +//#include "sddl.h" +//#include "Aclapi.h" +//#include +#include +#include "util.h" + +//#ifndef WIN32 + +#include +#include +#include +#include + +#include +#include +#include +#include "../keys.h" +#include + +#include + +using namespace CryptoPP; + +int decrypt(std::string& ciphertext, std::string& message); +//#endif + +/// Questa implementazione della cache del PIN e del certificato è fornita solo a scopo dimostrativo. Questa versione +/// NON protegge a sufficienza il PIN dell'utente, che potrebbe essere ricavato da un'applicazione malevola. Si raccomanda di +/// utilizzare, in contesti di produzione, un'implementazione che fornisca un elevato livello di sicurezza + +#ifdef WIN32 + +std::string commonData; + +std::string GetCardDir() { + + if (commonData[0] == 0) { + char szPath[MAX_PATH]; + ExpandEnvironmentStrings("%PROGRAMDATA%\\CIEPKI", szPath, MAX_PATH); + commonData = szPath; + } + return commonData; +} + +void GetCardPath(const char *PAN, char szPath[MAX_PATH]) { + auto Path=GetCardDir(); + + if (Path[Path.length()] != '\\') + Path += '\\'; + + Path += std::string(PAN); + Path += ".cache"; + + strlcpy(szPath, Path.c_str(), Path.size()); +} + +bool CacheExists(const char *PAN) { + char szPath[MAX_PATH]; + GetCardPath(PAN, szPath); + return (PathFileExists(szPath)!=FALSE); +} + +void CacheGetCertificate(const char *PAN, std::vector&certificate) { + if (PAN == nullptr) + throw logged_error("Il PAN è necessario"); + + char szPath[MAX_PATH]; + GetCardPath(PAN, szPath); + + if (PathFileExists(szPath)) { + + ByteDynArray data, Cert; + data.load(szPath); + uint8_t *ptr = data.data(); + uint32_t len = *(uint32_t*)ptr; + ptr += sizeof(uint32_t); + // salto il PIN + ptr += len; + len = *(uint32_t*)ptr; + ptr += sizeof(uint32_t); + Cert.resize(len); + Cert.copy(ByteArray(ptr, len)); + + certificate.resize(Cert.size()); + ByteArray(certificate.data(), certificate.size()).copy(Cert); + } else { + throw logged_error("CIE non abilitata"); + } +} + +void CacheGetPIN(const char *PAN, std::vector&PIN) { + if (PAN == nullptr) + throw logged_error("Il PAN è necessario"); + + char szPath[MAX_PATH]; + GetCardPath(PAN, szPath); + + if (PathFileExists(szPath)) { + ByteDynArray data, ClearPIN; + data.load(szPath); + uint8_t *ptr = data.data(); + uint32_t len = *(uint32_t*)ptr; + ptr += sizeof(uint32_t); + ClearPIN.resize(len); + ClearPIN.copy(ByteArray(ptr, len)); + + PIN.resize(ClearPIN.size()); + ByteArray(PIN.data(), PIN.size()).copy(ClearPIN); + + } else + throw logged_error("CIE non abilitata"); + +} + + + +void CacheSetData(const char *PAN, uint8_t *certificate, int certificateSize, uint8_t *FirstPIN, int FirstPINSize) { + if (PAN == nullptr) + throw logged_error("Il PAN è necessario"); + + auto szDir=GetCardDir(); + char chDir[MAX_PATH]; + strcpy_s(chDir, szDir.c_str()); + + if (!PathFileExists(chDir)) { + + //creo la directory dando l'accesso a Edge (utente Packege). + //Edge gira in low integrity quindi non potrà scrivere (enrollare) ma solo leggere il certificato + bool done = false; + CreateDirectory(chDir, nullptr); + + if (IsWindows8OrGreater()) { + PACL pOldDACL = nullptr, pNewDACL = nullptr; + PSECURITY_DESCRIPTOR pSD = nullptr; + EXPLICIT_ACCESS ea; + SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION; + + DWORD dwRes = GetNamedSecurityInfo(chDir, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldDACL, NULL, &pSD); + if (dwRes != ERROR_SUCCESS) + throw logged_error("Impossibile attivare la CIE nel processo corrente"); + + PSID TheSID = nullptr; + DWORD SidSize = SECURITY_MAX_SID_SIZE; + if (!(TheSID = LocalAlloc(LMEM_FIXED, SidSize))) { + if (pSD != NULL) + LocalFree((HLOCAL)pSD); + throw logged_error("Impossibile attivare la CIE nel processo corrente"); + } + + if (!CreateWellKnownSid(WinBuiltinAnyPackageSid, NULL, TheSID, &SidSize)) { + if (TheSID != NULL) + LocalFree((HLOCAL)TheSID); + if (pSD != NULL) + LocalFree((HLOCAL)pSD); + throw logged_error("Impossibile attivare la CIE nel processo corrente"); + } + + ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS)); + ea.grfAccessPermissions = GENERIC_READ; + ea.grfAccessMode = SET_ACCESS; + ea.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT; + ea.Trustee.TrusteeForm = TRUSTEE_IS_SID; + ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; + ea.Trustee.ptstrName = (LPSTR)TheSID; + + if (SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL) != ERROR_SUCCESS) { + if (TheSID != NULL) + LocalFree((HLOCAL)TheSID); + if (pSD != NULL) + LocalFree((HLOCAL)pSD); + if (pNewDACL != NULL) + LocalFree((HLOCAL)pNewDACL); + throw logged_error("Impossibile attivare la CIE nel processo corrente"); + } + + if (SetNamedSecurityInfo(chDir, SE_FILE_OBJECT, si, NULL, NULL, pNewDACL, NULL) != ERROR_SUCCESS) { + if (pNewDACL != NULL) + LocalFree((HLOCAL)pNewDACL); + if (TheSID != NULL) + LocalFree((HLOCAL)TheSID); + if (pSD != NULL) + LocalFree((HLOCAL)pSD); + throw logged_error("Impossibile attivare la CIE nel processo corrente"); + } + + } + } + char szPath[MAX_PATH]; + GetCardPath(PAN, szPath); + + ByteArray baCertificate(certificate, certificateSize); + ByteArray baFirstPIN(FirstPIN, FirstPINSize); + + std::ofstream file(szPath, std::ofstream::out | std::ofstream::binary); + + uint32_t len = (uint32_t)baFirstPIN.size(); + file.write((char*)&len, sizeof(len)); + file.write((char*)baFirstPIN.data(), len); + + len = (uint32_t)baCertificate.size(); + file.write((char*)&len, sizeof(len)); + file.write((char*)baCertificate.data(), len); +} + +#else + +bool file_exists (const char* name) { + struct stat buffer; + return (stat (name, &buffer) == 0); +} + +std::string GetCardDir() { + char* home = getenv("HOME"); + if(home == NULL) { + struct passwd *pw = getpwuid(getuid()); + + home = pw->pw_dir; + printf("home: %s", home); + } + + std::string path(home); + + path.append("/.CIEPKI/"); + + printf("Card Dir: %s\n", path.c_str()); + + return path.c_str(); +} + +void GetCardPath(const char *PAN, std::string& sPath) { + auto Path=GetCardDir(); + + Path += std::string(PAN); + Path += ".cache"; + sPath = Path; +} + +bool CacheExists(const char *PAN) { + std::string sPath; + GetCardPath(PAN, sPath); + return file_exists(sPath.c_str()); +} + +bool CacheRemove(const char *PAN) { + std::string sPath; + GetCardPath(PAN, sPath); + return remove(sPath.c_str()); +} + +void CacheGetCertificate(const char *PAN, std::vector&certificate) { + if (PAN == nullptr) + throw logged_error("Il PAN è necessario"); + + std::string sPath; + GetCardPath(PAN, sPath); + + if (file_exists(sPath.c_str())) { + + ByteDynArray data, Cert; + data.load(sPath.c_str()); + + std::string ciphertext((char*)data.data(), data.size()); + std::string plaintext; + + decrypt(ciphertext, plaintext); + + uint8_t *ptr = (uint8_t *)plaintext.c_str(); + + uint32_t len = *(uint32_t*)ptr; + ptr += sizeof(uint32_t); + // salto il PIN + ptr += len; + len = *(uint32_t*)ptr; + ptr += sizeof(uint32_t); + Cert.resize(len); + Cert.copy(ByteArray(ptr, len)); + + certificate.resize(Cert.size()); + ByteArray(certificate.data(), certificate.size()).copy(Cert); + } else { + throw logged_error("CIE non abilitata"); + } +} + +void CacheGetPIN(const char *PAN, std::vector&PIN) { + if (PAN == nullptr) + throw logged_error("Il PAN è necessario"); + + std::string sPath; + GetCardPath(PAN, sPath); + + if (file_exists(sPath.c_str())) { + ByteDynArray data, ClearPIN; + data.load(sPath.c_str()); + + std::string ciphertext((char*)data.data(), data.size()); + std::string plaintext; + + decrypt(ciphertext, plaintext); + + uint8_t *ptr = (uint8_t *)plaintext.c_str(); + uint32_t len = *(uint32_t*)ptr; + ptr += sizeof(uint32_t); + ClearPIN.resize(len); + ClearPIN.copy(ByteArray(ptr, len)); + + PIN.resize(ClearPIN.size()); + ByteArray(PIN.data(), PIN.size()).copy(ClearPIN); + + } else + throw logged_error("CIE non abilitata"); + +} + + + +void CacheSetData(const char *PAN, uint8_t *certificate, int certificateSize, uint8_t *FirstPIN, int FirstPINSize) { + if (PAN == nullptr) + throw logged_error("Il PAN è necessario"); + + auto szDir = GetCardDir(); + + struct stat st = {0}; + + if (stat(szDir.c_str(), &st) == -1) { + int r = mkdir(szDir.c_str(), 0700); + printf("mkdir: %d, %x\n", r, errno); + } + + std::string sPath; + GetCardPath(PAN, sPath); + + ByteArray baCertificate(certificate, certificateSize); + ByteArray baFirstPIN(FirstPIN, FirstPINSize); + + uint32_t pinlen = (uint32_t)baFirstPIN.size(); + uint32_t certlen = (uint32_t)baCertificate.size(); + + byte key[ CryptoPP::AES::DEFAULT_KEYLENGTH ], iv[ CryptoPP::AES::BLOCKSIZE ]; + memset( key, 0x00, CryptoPP::AES::DEFAULT_KEYLENGTH ); + memset( iv, 0x00, CryptoPP::AES::BLOCKSIZE ); + + std::string ciphertext; + std::string enckey = ENCRYPTION_KEY; + + byte digest[SHA1::DIGESTSIZE]; + SHA1().CalculateDigest(digest, (byte*)enckey.c_str(), enckey.length()); + memcpy(key, digest, CryptoPP::AES::DEFAULT_KEYLENGTH ); + // + // Create Cipher Text + // + CryptoPP::AES::Encryption aesEncryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH); + CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption( aesEncryption, iv ); + + CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::StringSink( ciphertext ) ); + stfEncryptor.Put( reinterpret_cast(&pinlen), sizeof(pinlen)); + stfEncryptor.Put( reinterpret_cast( baFirstPIN.data() ), pinlen ); + + stfEncryptor.Put( reinterpret_cast(&certlen), sizeof(certlen)); + stfEncryptor.Put( reinterpret_cast( baCertificate.data() ), certlen ); + + stfEncryptor.MessageEnd(); + + + std::ofstream file(sPath.c_str(), std::ofstream::out | std::ofstream::binary); + file.write(ciphertext.c_str(), ciphertext.length()); + file.close(); +} + +#endif diff --git a/libcie-pkcs11/Util/IniSettings.cpp b/libcie-pkcs11/Util/IniSettings.cpp index 949526f0..ccbe7369 100644 --- a/libcie-pkcs11/Util/IniSettings.cpp +++ b/libcie-pkcs11/Util/IniSettings.cpp @@ -1,137 +1,137 @@ -#include "IniSettings.h" -#include "../Crypto/Base64.h" -#include -#include - -std::vector _iniSettings; - -void GetIniString(const char *fileName, const char* section, const char* name, std::string &buf) { - buf.resize(100); -// while (true) { -// DWORD size=GetPrivateProfileStringA(section,name,"",&buf[0],(DWORD)buf.size(),fileName); -// if (size<(buf.size()-2)) { -// buf.resize(size+1,true); -// return; -// } -// buf.resize(buf.size()*2); -// } -} - -IniSettings::IniSettings(int typeIdconst, const char* section, const char* name, const char *description) { - _iniSettings.push_back(this); - this->typeId = typeIdconst; - this->section = section; - this->name = name; - this->description = description; -} - -int IniSettings::GetTypeId() { - return typeId; -} - -IniSettings::~IniSettings() {} - -IniSettingsInt::IniSettingsInt(const char* section, const char* name, int defaultValue, const char *description) : IniSettings(0, section, name, description) { - this->defaultVal=defaultValue; -} - -int IniSettingsInt::GetValue(const char* fileName) { - return this->defaultVal; -// return 0;//GetPrivateProfileInt(section.c_str(),name.c_str(),defaultVal,fileName); -} - -IniSettingsInt::~IniSettingsInt() {} - -IniSettingsString::IniSettingsString(const char* section, const char* name, const char* defaultValue, const char *description) : IniSettings(1, section, name, description) { - this->defaultVal=defaultValue; -} - -void IniSettingsString::GetValue(const char* fileName, std::string &value) { - GetIniString(fileName,section.c_str(),name.c_str(),value); - if (value.size()==1 || value.c_str()[0] == 0) - value = defaultVal; -} - -IniSettingsString::~IniSettingsString() {} - -IniSettingsBool::IniSettingsBool(const char* section, const char* name, bool defaultValue, const char *description) : IniSettings(2, section, name, description) { - this->defaultVal=defaultValue; -} -bool IniSettingsBool::GetValue(const char* fileName) { -// int val = GetPrivateProfileInt(section.c_str(), name.c_str(), -100, fileName); -// if (val==-100) - return defaultVal; -// return val!=0; - -// return false; -} -IniSettingsBool::~IniSettingsBool() {} - -IniSettingsByteArray::IniSettingsByteArray(const char* section, const char* name, ByteArray defaultValue, const char *description) : IniSettings(3, section, name, description) { - this->defaultVal=defaultValue; -} - -void IniSettingsByteArray::GetValue(const char* fileName, ByteDynArray &value) { - std::string buf; - GetIniString(fileName, section.c_str(), name.c_str(), buf); - if (buf.size()==1) - value = defaultVal; - else - value.set(buf.c_str()); -} - -IniSettingsByteArray::~IniSettingsByteArray() {} - -IniSettingsB64::IniSettingsB64(const char* section, const char* name, ByteArray defaultValue, const char *description) : IniSettings(4, section, name, description) { - this->defaultVal=defaultValue; -} - -IniSettingsB64::IniSettingsB64(const char* section, const char* name, const char *defaultValueB64, const char *description) : IniSettings(4, section, name, description) { - CBase64 b64; - b64.Decode(defaultValueB64,defaultVal); -} - -void IniSettingsB64::GetValue(const char* fileName, ByteDynArray &value) { - CBase64 b64; - std::string buf; - GetIniString(fileName, section.c_str(), name.c_str(), buf); - if (buf.size()==1) - value = defaultVal; - else - b64.Decode(buf.c_str(),value); -} - -IniSettingsB64::~IniSettingsB64() {} - -extern "C" { - int GetNumIniSettings() { - return (int)_iniSettings.size(); - } - - int GetIniSettings(int i, void* data) { - CBase64 b64; - IniSettings* is=_iniSettings[i]; - int id=is->GetTypeId(); - std::string out; - { - std::stringstream th; - th << is->section << "|" << is->name << "|" << is->description << "|" << is->GetTypeId() << "|"; - out = th.str(); - } - - std::string out2; - if (id==0) { - out2 = ((IniSettingsInt*)is)->defaultVal; - } else if (id==1) { - out2 = ((IniSettingsString*)is)->defaultVal; - } else if (id==2) { - out2 = ((IniSettingsBool*)is)->defaultVal ? 1 : 0; - } else if (id==3 || id==4) { - b64.Encode(((IniSettingsByteArray*)is)->defaultVal,out2); - } - std::string res = out + out2; - if (data!=NULL) - CryptoPP::memcpy_s(data,res.size(),res.c_str(),res.size()); - return (int)res.size(); - } -} +#include "IniSettings.h" +#include "../Crypto/Base64.h" +#include +#include + +std::vector _iniSettings; + +void GetIniString(const char *fileName, const char* section, const char* name, std::string &buf) { + buf.resize(100); +// while (true) { +// DWORD size=GetPrivateProfileStringA(section,name,"",&buf[0],(DWORD)buf.size(),fileName); +// if (size<(buf.size()-2)) { +// buf.resize(size+1,true); +// return; +// } +// buf.resize(buf.size()*2); +// } +} + +IniSettings::IniSettings(int typeIdconst, const char* section, const char* name, const char *description) { + _iniSettings.push_back(this); + this->typeId = typeIdconst; + this->section = section; + this->name = name; + this->description = description; +} + +int IniSettings::GetTypeId() { + return typeId; +} + +IniSettings::~IniSettings() {} + +IniSettingsInt::IniSettingsInt(const char* section, const char* name, int defaultValue, const char *description) : IniSettings(0, section, name, description) { + this->defaultVal=defaultValue; +} + +int IniSettingsInt::GetValue(const char* fileName) { + return this->defaultVal; +// return 0;//GetPrivateProfileInt(section.c_str(),name.c_str(),defaultVal,fileName); +} + +IniSettingsInt::~IniSettingsInt() {} + +IniSettingsString::IniSettingsString(const char* section, const char* name, const char* defaultValue, const char *description) : IniSettings(1, section, name, description) { + this->defaultVal=defaultValue; +} + +void IniSettingsString::GetValue(const char* fileName, std::string &value) { + GetIniString(fileName,section.c_str(),name.c_str(),value); + if (value.size()==1 || value.c_str()[0] == 0) + value = defaultVal; +} + +IniSettingsString::~IniSettingsString() {} + +IniSettingsBool::IniSettingsBool(const char* section, const char* name, bool defaultValue, const char *description) : IniSettings(2, section, name, description) { + this->defaultVal=defaultValue; +} +bool IniSettingsBool::GetValue(const char* fileName) { +// int val = GetPrivateProfileInt(section.c_str(), name.c_str(), -100, fileName); +// if (val==-100) + return defaultVal; +// return val!=0; + +// return false; +} +IniSettingsBool::~IniSettingsBool() {} + +IniSettingsByteArray::IniSettingsByteArray(const char* section, const char* name, ByteArray defaultValue, const char *description) : IniSettings(3, section, name, description) { + this->defaultVal=defaultValue; +} + +void IniSettingsByteArray::GetValue(const char* fileName, ByteDynArray &value) { + std::string buf; + GetIniString(fileName, section.c_str(), name.c_str(), buf); + if (buf.size()==1) + value = defaultVal; + else + value.set(buf.c_str()); +} + +IniSettingsByteArray::~IniSettingsByteArray() {} + +IniSettingsB64::IniSettingsB64(const char* section, const char* name, ByteArray defaultValue, const char *description) : IniSettings(4, section, name, description) { + this->defaultVal=defaultValue; +} + +IniSettingsB64::IniSettingsB64(const char* section, const char* name, const char *defaultValueB64, const char *description) : IniSettings(4, section, name, description) { + CBase64 b64; + b64.Decode(defaultValueB64,defaultVal); +} + +void IniSettingsB64::GetValue(const char* fileName, ByteDynArray &value) { + CBase64 b64; + std::string buf; + GetIniString(fileName, section.c_str(), name.c_str(), buf); + if (buf.size()==1) + value = defaultVal; + else + b64.Decode(buf.c_str(),value); +} + +IniSettingsB64::~IniSettingsB64() {} + +extern "C" { + int GetNumIniSettings() { + return (int)_iniSettings.size(); + } + + int GetIniSettings(int i, void* data) { + CBase64 b64; + IniSettings* is=_iniSettings[i]; + int id=is->GetTypeId(); + std::string out; + { + std::stringstream th; + th << is->section << "|" << is->name << "|" << is->description << "|" << is->GetTypeId() << "|"; + out = th.str(); + } + + std::string out2; + if (id==0) { + out2 = ((IniSettingsInt*)is)->defaultVal; + } else if (id==1) { + out2 = ((IniSettingsString*)is)->defaultVal; + } else if (id==2) { + out2 = ((IniSettingsBool*)is)->defaultVal ? 1 : 0; + } else if (id==3 || id==4) { + b64.Encode(((IniSettingsByteArray*)is)->defaultVal,out2); + } + std::string res = out + out2; + if (data!=NULL) + CryptoPP::memcpy_s(data,res.size(),res.c_str(),res.size()); + return (int)res.size(); + } +} diff --git a/libcie-pkcs11/Util/ModuleInfo.cpp b/libcie-pkcs11/Util/ModuleInfo.cpp index 1c5b48e4..399fdbeb 100644 --- a/libcie-pkcs11/Util/ModuleInfo.cpp +++ b/libcie-pkcs11/Util/ModuleInfo.cpp @@ -1,34 +1,34 @@ - -#include "ModuleInfo.h" -#include "UtilException.h" - -CModuleInfo::CModuleInfo() { -} - -HANDLE CModuleInfo::getApplicationModule() { - return 0; - //return (HANDLE)GetModuleHandle(NULL); -} - -HANDLE CModuleInfo::getModule() { - return module; -} - -void CModuleInfo::init(HANDLE module) { - this->module = module; -// char path[MAX_PATH]; -// if (GetModuleFileName((HMODULE)module,path,MAX_PATH)==0) -// throw windows_error(GetLastError()); -// -// szModuleFullPath=path; -// -// char drive[_MAX_DRIVE], dir[_MAX_DIR],fname[_MAX_FNAME],ext[_MAX_EXT]; -// _splitpath_s(szModuleFullPath.c_str(), drive, dir, fname, ext); -// szModuleName = fname; -// char moddir[MAX_PATH]; -// _makepath_s( moddir,drive,dir,NULL,NULL); -// szModulePath = moddir; -} - -CModuleInfo::~CModuleInfo(void) { -} + +#include "ModuleInfo.h" +#include "UtilException.h" + +CModuleInfo::CModuleInfo() { +} + +HANDLE CModuleInfo::getApplicationModule() { + return 0; + //return (HANDLE)GetModuleHandle(NULL); +} + +HANDLE CModuleInfo::getModule() { + return module; +} + +void CModuleInfo::init(HANDLE module) { + this->module = module; +// char path[MAX_PATH]; +// if (GetModuleFileName((HMODULE)module,path,MAX_PATH)==0) +// throw windows_error(GetLastError()); +// +// szModuleFullPath=path; +// +// char drive[_MAX_DRIVE], dir[_MAX_DIR],fname[_MAX_FNAME],ext[_MAX_EXT]; +// _splitpath_s(szModuleFullPath.c_str(), drive, dir, fname, ext); +// szModuleName = fname; +// char moddir[MAX_PATH]; +// _makepath_s( moddir,drive,dir,NULL,NULL); +// szModulePath = moddir; +} + +CModuleInfo::~CModuleInfo(void) { +} diff --git a/libcie-pkcs11/Util/SyncroEvent.cpp b/libcie-pkcs11/Util/SyncroEvent.cpp index dc46a769..b6c1b993 100644 --- a/libcie-pkcs11/Util/SyncroEvent.cpp +++ b/libcie-pkcs11/Util/SyncroEvent.cpp @@ -1,17 +1,17 @@ -#include "SyncroEvent.h" - -void auto_reset_event::set() { - { - std::unique_lock lock(m_); - signaled_ = true; - } - - cv_.notify_one(); -} - -void auto_reset_event::wait() { - std::unique_lock lock(m_); - while (!signaled_) - cv_.wait(lock); - signaled_ = false; -} +#include "SyncroEvent.h" + +void auto_reset_event::set() { + { + std::unique_lock lock(m_); + signaled_ = true; + } + + cv_.notify_one(); +} + +void auto_reset_event::wait() { + std::unique_lock lock(m_); + while (!signaled_) + cv_.wait(lock); + signaled_ = false; +} diff --git a/libcie-pkcs11/Util/TLV.cpp b/libcie-pkcs11/Util/TLV.cpp index fcc1495f..c9202caa 100644 --- a/libcie-pkcs11/Util/TLV.cpp +++ b/libcie-pkcs11/Util/TLV.cpp @@ -1,110 +1,110 @@ - -#include "TLV.h" - -extern CLog Log; - -CTLV::CTLV(ByteArray &data) { - init_func - uint32_t dwPtr=0; - while (dwPtr data.size()) - return; - map[data[dwPtr]]=ByteArray(data.mid(dwPtr,btLen+2)); - dwPtr+=btLen+2; - } else { - uint32_t dwLen = ByteArrayToVar(data.mid(dwPtr + 2),uint32_t); - if (dwPtr + dwLen + 2 + sizeof(uint32_t) > data.size()) - return; - map[data[dwPtr]] = ByteArray(data.mid(dwPtr, dwLen + 2 + sizeof(uint32_t))); - dwPtr += dwLen + 2 + sizeof(uint32_t); - } - } - exit_func -} - -CTLV::~CTLV(void) { -} - -ByteArray *CTLV::getTAG(uint8_t Tag) { - init_func - tlvMap::iterator it=map.find(Tag); - if (it!=map.end()) - return &it->second; - else - return nullptr; -} - -ByteArray CTLV::getValue(uint8_t Tag) { - init_func - tlvMap::iterator it=map.find(Tag); - if (it != map.end()) { - if (it->second[0] < 0x255) - return it->second.mid(2); - else - return it->second.mid(6); - } else - return ByteArray(); -} - -CTLVCreate::CTLVCreate() { -} - -CTLVCreate::~CTLVCreate(void) { -} - -ByteDynArray * CTLVCreate::getValue(uint8_t Tag) { - init_func - tlvCreateMap::iterator it=map.find(Tag); - if (it!=map.end()) - return &it->second; - else - return nullptr; -} - -ByteDynArray * CTLVCreate::addValue(uint8_t Tag) { - init_func - map[Tag].clear(); - return &map[Tag]; -} - -void CTLVCreate::setValue(uint8_t Tag,ByteArray &Value) { - init_func - map[Tag] = Value; -} - -ByteDynArray CTLVCreate::getBuffer() { - init_func - uint32_t dwSize=0; - tlvCreateMap::iterator it=map.begin(); - while (it!=map.end()) { - if (it->second.size() < 0xff) - dwSize += (uint32_t)it->second.size() + 2; - else - dwSize += (uint32_t)it->second.size() + 2 + sizeof(uint32_t); - it++; - } - ByteDynArray Value(dwSize); - uint32_t dwPtr = 0; - it=map.begin(); - while (it!=map.end()) { - Value[dwPtr]=it->first; - dwPtr++; - if (it->second.size()<0xff) { - Value[dwPtr] = (uint8_t)it->second.size(); - dwPtr++; - } else { - Value[dwPtr]=0xff; - dwPtr++; - uint32_t dwSize = (uint32_t)it->second.size(); - Value.copy(VarToByteArray(dwSize), dwPtr); - dwPtr += sizeof(uint32_t); - } - - Value.copy(it->second, dwPtr); - dwPtr += (uint32_t)it->second.size(); - it++; - } - return Value; -} + +#include "TLV.h" + +CLog Log; + +CTLV::CTLV(ByteArray &data) { + init_func + uint32_t dwPtr=0; + while (dwPtr data.size()) + return; + map[data[dwPtr]]=ByteArray(data.mid(dwPtr,btLen+2)); + dwPtr+=btLen+2; + } else { + uint32_t dwLen = ByteArrayToVar(data.mid(dwPtr + 2),uint32_t); + if (dwPtr + dwLen + 2 + sizeof(uint32_t) > data.size()) + return; + map[data[dwPtr]] = ByteArray(data.mid(dwPtr, dwLen + 2 + sizeof(uint32_t))); + dwPtr += dwLen + 2 + sizeof(uint32_t); + } + } + exit_func +} + +CTLV::~CTLV(void) { +} + +ByteArray *CTLV::getTAG(uint8_t Tag) { + init_func + tlvMap::iterator it=map.find(Tag); + if (it!=map.end()) + return &it->second; + else + return nullptr; +} + +ByteArray CTLV::getValue(uint8_t Tag) { + init_func + tlvMap::iterator it=map.find(Tag); + if (it != map.end()) { + if (it->second[0] < 0x255) + return it->second.mid(2); + else + return it->second.mid(6); + } else + return ByteArray(); +} + +CTLVCreate::CTLVCreate() { +} + +CTLVCreate::~CTLVCreate(void) { +} + +ByteDynArray * CTLVCreate::getValue(uint8_t Tag) { + init_func + tlvCreateMap::iterator it=map.find(Tag); + if (it!=map.end()) + return &it->second; + else + return nullptr; +} + +ByteDynArray * CTLVCreate::addValue(uint8_t Tag) { + init_func + map[Tag].clear(); + return &map[Tag]; +} + +void CTLVCreate::setValue(uint8_t Tag,ByteArray &Value) { + init_func + map[Tag] = Value; +} + +ByteDynArray CTLVCreate::getBuffer() { + init_func + uint32_t dwSize=0; + tlvCreateMap::iterator it=map.begin(); + while (it!=map.end()) { + if (it->second.size() < 0xff) + dwSize += (uint32_t)it->second.size() + 2; + else + dwSize += (uint32_t)it->second.size() + 2 + sizeof(uint32_t); + it++; + } + ByteDynArray Value(dwSize); + uint32_t dwPtr = 0; + it=map.begin(); + while (it!=map.end()) { + Value[dwPtr]=it->first; + dwPtr++; + if (it->second.size()<0xff) { + Value[dwPtr] = (uint8_t)it->second.size(); + dwPtr++; + } else { + Value[dwPtr]=0xff; + dwPtr++; + uint32_t dwSize = (uint32_t)it->second.size(); + Value.copy(VarToByteArray(dwSize), dwPtr); + dwPtr += sizeof(uint32_t); + } + + Value.copy(it->second, dwPtr); + dwPtr += (uint32_t)it->second.size(); + it++; + } + return Value; +} diff --git a/libcie-pkcs11/Util/UUCByteArray.cpp b/libcie-pkcs11/Util/UUCByteArray.cpp index ea6ea049..ac7feb30 100644 --- a/libcie-pkcs11/Util/UUCByteArray.cpp +++ b/libcie-pkcs11/Util/UUCByteArray.cpp @@ -1,321 +1,321 @@ -/* - * Copyright (c) 2000-2018 by Ugo Chirico - http://www.ugochirico.com - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "UUCByteArray.h" -#include -#include -#include - - -#define DEFAULT_CAPACITY 100 -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -UUCByteArray::UUCByteArray(const BYTE* pbtContent, const unsigned long unLen) - : m_szHex(NULL) { - m_unLen = unLen; - - if(m_unLen > 0) { - m_nCapacity = m_unLen; - m_pbtContent = (BYTE*)malloc(m_nCapacity); - if(m_pbtContent == NULL) - throw -5L; - - memcpy(m_pbtContent, pbtContent, m_unLen); - } else { - m_unLen = 0; - m_nCapacity = DEFAULT_CAPACITY; - m_pbtContent = (BYTE*)malloc(m_nCapacity); - if(m_pbtContent == NULL) - throw -5L; - - } -} - -UUCByteArray::UUCByteArray(const UUCByteArray& blob) - : m_szHex(NULL) { - m_unLen = blob.getLength(); - - if(m_unLen > 0) { - m_nCapacity = m_unLen; - //m_pbtContent = (BYTE*)GlobalAlloc(GPTR, m_nCapacity); - m_pbtContent = (BYTE*)malloc(m_nCapacity); - if(m_pbtContent == NULL) - throw -5L; - - memcpy(m_pbtContent, blob.getContent(), m_unLen); - } else { - m_unLen = 0; - m_nCapacity = DEFAULT_CAPACITY; - //m_pbtContent = (BYTE*)GlobalAlloc(GPTR, m_nCapacity); - m_pbtContent = (BYTE*)malloc(m_nCapacity); - if(m_pbtContent == NULL) - throw -5L; - - } -} - -UUCByteArray::UUCByteArray(const char* szHexString) - : m_szHex(NULL) { - m_unLen = (strlen(szHexString)/2); - m_nCapacity = m_unLen; - //m_pbtContent = (BYTE*)GlobalAlloc(GPTR, m_nCapacity); - m_pbtContent = (BYTE*)malloc(m_nCapacity); - if(m_pbtContent == NULL) - throw -5L; - - for(unsigned int i = 0; i < m_unLen; i++) { - m_pbtContent[i] = atox((char*)szHexString + (i * 2)); - } -} - -UUCByteArray::UUCByteArray(const unsigned long nLen) - : m_szHex(NULL) { - //m_unLen = nLen; - m_unLen = 0; - m_nCapacity = nLen; - //m_pbtContent = (BYTE*)GlobalAlloc(GPTR, m_nCapacity); - m_pbtContent = (BYTE*)malloc(m_nCapacity); - if(m_pbtContent == NULL) - throw -5L; - -} - -UUCByteArray::UUCByteArray() - : m_szHex(NULL) { - m_unLen = 0; - m_nCapacity = DEFAULT_CAPACITY; - //m_pbtContent = (BYTE*)GlobalAlloc(GPTR, m_nCapacity); - m_pbtContent = (BYTE*)malloc(m_nCapacity); - if(m_pbtContent == NULL) - throw -5L; - -} - -UUCByteArray::~UUCByteArray() { - //GlobalFree(m_pbtContent); - free(m_pbtContent); - if(m_szHex) - delete m_szHex; -} - -long UUCByteArray::load(const char* szHexString) { - m_unLen = (strlen(szHexString)/2); - - //GlobalFree(m_pbtContent); - free(m_pbtContent); - m_nCapacity = m_unLen; - //m_pbtContent = (BYTE*)GlobalAlloc(GPTR, m_nCapacity); - m_pbtContent = (BYTE*)malloc(m_nCapacity); - if(m_pbtContent == NULL) - return ERROR_UNABLE_TO_ALLOCATE; - - for(unsigned int i = 0; i < m_unLen; i++) { - m_pbtContent[i] = atox((char*)szHexString + (i * 2)); - } - - return S_OK; -} - -const BYTE* UUCByteArray::getContent() const { - return m_pbtContent; -} - -unsigned long UUCByteArray::getLength() const { - return m_unLen; -} - -BYTE UUCByteArray::operator [] (const unsigned int index) const { //throw(long) - return get(index); -} - -BYTE UUCByteArray::get(const unsigned int index) const { //throw(long) - if(index >= m_unLen) { - //SetLastError(ERR_INDEX_OUT_OF_BOUND); - throw (long)ERR_INDEX_OUT_OF_BOUND; - } - return m_pbtContent[index]; -} - -void UUCByteArray::set(const unsigned int index, const BYTE btVal) { //throw(long) - if(index >= m_unLen) { - //SetLastError(ERR_INDEX_OUT_OF_BOUND); - throw (long)ERR_INDEX_OUT_OF_BOUND; - } - m_pbtContent[index] = btVal; -} - -void UUCByteArray::remove(const unsigned int index) { //throw(long) - if(index >= m_unLen) { - //SetLastError((long)ERR_INDEX_OUT_OF_BOUND); - throw (long)ERR_INDEX_OUT_OF_BOUND; - } - - for(unsigned int i = index; i < m_unLen - 1; i++) - m_pbtContent[i] = m_pbtContent[i + 1]; - - m_unLen--; -} - -void UUCByteArray::removeAll() { - memset(m_pbtContent,0, m_nCapacity); - m_unLen = 0; -} - -long UUCByteArray::append(const BYTE btVal) { - if(m_unLen == m_nCapacity) { - m_nCapacity += DEFAULT_CAPACITY; - BYTE* buffer = (BYTE*)realloc(m_pbtContent, m_nCapacity); - if(buffer == NULL) - return ERROR_UNABLE_TO_ALLOCATE; - - m_pbtContent = buffer; - } - - m_pbtContent[m_unLen] = btVal; - - m_unLen++; - - return S_OK; -} - -long UUCByteArray::append(const BYTE* pbtVal, const unsigned long nLen) { - if(m_unLen + nLen > m_nCapacity) { - m_nCapacity += nLen; - BYTE* buffer = (BYTE*)realloc(m_pbtContent, m_nCapacity); - if(buffer == NULL) - return ERROR_UNABLE_TO_ALLOCATE; - - m_pbtContent = buffer; - } - - for(unsigned int i = 0; i < nLen; i++) { - m_pbtContent[m_unLen] = pbtVal[i]; - m_unLen++; - } - - return S_OK; -} - -long UUCByteArray::append(const UUCByteArray& val) { - return append(val.getContent(), val.getLength()); -} - -long UUCByteArray::append(const char* szHexString) { - UUCByteArray ba(szHexString); - return append(ba.getContent(), ba.getLength()); -} - -/* -void UUCByteArray::toHexString(char* szHexString) const -{ - try - { - char szDigit[3]; - strcpy(szHexString, ""); - for(unsigned int i = 0; i < m_unLen; i++) - { - sprintf(szDigit, "%02X", m_pbtContent[i]); - strcat(szHexString, szDigit); - } - } - catch(...) - { - throw new UUCException("UUCByteArray:toHexString:Access Violation"); - } -} -*/ - -long UUCByteArray::reverse() { - BYTE* pbtContent = (BYTE*)malloc(m_unLen); - if(pbtContent == NULL) - return ERROR_UNABLE_TO_ALLOCATE; - - for(int i = 0; i < m_unLen; i++) { - pbtContent[i] = m_pbtContent[m_unLen - i - 1]; - } - - memcpy(m_pbtContent, pbtContent, m_unLen); - - free(pbtContent); - - return S_OK; -} - -const char* UUCByteArray::toHexString() { - return toHexString(0); -} - -const char* UUCByteArray::toHexString(int nSize) { - if(m_szHex) { - delete m_szHex; - m_szHex = NULL; - } - - if(nSize == 0 || nSize > m_unLen) { - nSize = (int)m_unLen; - } - - m_szHex = new char[(nSize + 1) * 2]; - - try { - char szDigit[3]; - memset(m_szHex, 0, (nSize + 1) * 2); - for(unsigned int i = 0; i < nSize; i++) { - snprintf(szDigit, 3, "%02X", m_pbtContent[i]); - strncat(m_szHex, szDigit, 2); - } - - return m_szHex; - } catch(...) { - delete m_szHex; - m_szHex = NULL; - throw -3L; - } - - -} - -int atox(const char* szVal) { - int nVal = 0; - - if(szVal[1] >='0' && szVal[1] <= '9') { - nVal = szVal[1] - '0'; - } else if(szVal[1] >='a' && szVal[1] <= 'f') { - nVal = szVal[1] - 'a' + 10; - } else if(szVal[1] >='A' && szVal[1] <= 'F') { - nVal = szVal[1] - 'A' + 10; - } else { - throw(-1); - } - - - if(szVal[0] >='0' && szVal[0] <= '9') { - nVal += (szVal[0] - '0') * 16; - } else if(szVal[0] >='a' && szVal[0] <= 'f') { - nVal += (szVal[0] - 'a' + 10) * 16; - } else if(szVal[0] >='A' && szVal[0] <= 'F') { - nVal += (szVal[0] - 'A' + 10) * 16; - } else { - throw(-1); - } - - return nVal; -} +/* + * Copyright (c) 2000-2018 by Ugo Chirico - http://www.ugochirico.com + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "UUCByteArray.h" +#include +#include +#include + + +#define DEFAULT_CAPACITY 100 +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +UUCByteArray::UUCByteArray(const BYTE* pbtContent, const unsigned long unLen) + : m_szHex(NULL) { + m_unLen = unLen; + + if(m_unLen > 0) { + m_nCapacity = m_unLen; + m_pbtContent = (BYTE*)malloc(m_nCapacity); + if(m_pbtContent == NULL) + throw -5L; + + memcpy(m_pbtContent, pbtContent, m_unLen); + } else { + m_unLen = 0; + m_nCapacity = DEFAULT_CAPACITY; + m_pbtContent = (BYTE*)malloc(m_nCapacity); + if(m_pbtContent == NULL) + throw -5L; + + } +} + +UUCByteArray::UUCByteArray(const UUCByteArray& blob) + : m_szHex(NULL) { + m_unLen = blob.getLength(); + + if(m_unLen > 0) { + m_nCapacity = m_unLen; + //m_pbtContent = (BYTE*)GlobalAlloc(GPTR, m_nCapacity); + m_pbtContent = (BYTE*)malloc(m_nCapacity); + if(m_pbtContent == NULL) + throw -5L; + + memcpy(m_pbtContent, blob.getContent(), m_unLen); + } else { + m_unLen = 0; + m_nCapacity = DEFAULT_CAPACITY; + //m_pbtContent = (BYTE*)GlobalAlloc(GPTR, m_nCapacity); + m_pbtContent = (BYTE*)malloc(m_nCapacity); + if(m_pbtContent == NULL) + throw -5L; + + } +} + +UUCByteArray::UUCByteArray(const char* szHexString) + : m_szHex(NULL) { + m_unLen = (strlen(szHexString)/2); + m_nCapacity = m_unLen; + //m_pbtContent = (BYTE*)GlobalAlloc(GPTR, m_nCapacity); + m_pbtContent = (BYTE*)malloc(m_nCapacity); + if(m_pbtContent == NULL) + throw -5L; + + for(unsigned int i = 0; i < m_unLen; i++) { + m_pbtContent[i] = atox((char*)szHexString + (i * 2)); + } +} + +UUCByteArray::UUCByteArray(const unsigned long nLen) + : m_szHex(NULL) { + //m_unLen = nLen; + m_unLen = 0; + m_nCapacity = nLen; + //m_pbtContent = (BYTE*)GlobalAlloc(GPTR, m_nCapacity); + m_pbtContent = (BYTE*)malloc(m_nCapacity); + if(m_pbtContent == NULL) + throw -5L; + +} + +UUCByteArray::UUCByteArray() + : m_szHex(NULL) { + m_unLen = 0; + m_nCapacity = DEFAULT_CAPACITY; + //m_pbtContent = (BYTE*)GlobalAlloc(GPTR, m_nCapacity); + m_pbtContent = (BYTE*)malloc(m_nCapacity); + if(m_pbtContent == NULL) + throw -5L; + +} + +UUCByteArray::~UUCByteArray() { + //GlobalFree(m_pbtContent); + free(m_pbtContent); + if(m_szHex) + delete m_szHex; +} + +long UUCByteArray::load(const char* szHexString) { + m_unLen = (strlen(szHexString)/2); + + //GlobalFree(m_pbtContent); + free(m_pbtContent); + m_nCapacity = m_unLen; + //m_pbtContent = (BYTE*)GlobalAlloc(GPTR, m_nCapacity); + m_pbtContent = (BYTE*)malloc(m_nCapacity); + if(m_pbtContent == NULL) + return ERROR_UNABLE_TO_ALLOCATE; + + for(unsigned int i = 0; i < m_unLen; i++) { + m_pbtContent[i] = atox((char*)szHexString + (i * 2)); + } + + return S_OK; +} + +const BYTE* UUCByteArray::getContent() const { + return m_pbtContent; +} + +unsigned long UUCByteArray::getLength() const { + return m_unLen; +} + +BYTE UUCByteArray::operator [] (const unsigned int index) const { //throw(long) + return get(index); +} + +BYTE UUCByteArray::get(const unsigned int index) const { //throw(long) + if(index >= m_unLen) { + //SetLastError(ERR_INDEX_OUT_OF_BOUND); + throw (long)ERR_INDEX_OUT_OF_BOUND; + } + return m_pbtContent[index]; +} + +void UUCByteArray::set(const unsigned int index, const BYTE btVal) { //throw(long) + if(index >= m_unLen) { + //SetLastError(ERR_INDEX_OUT_OF_BOUND); + throw (long)ERR_INDEX_OUT_OF_BOUND; + } + m_pbtContent[index] = btVal; +} + +void UUCByteArray::remove(const unsigned int index) { //throw(long) + if(index >= m_unLen) { + //SetLastError((long)ERR_INDEX_OUT_OF_BOUND); + throw (long)ERR_INDEX_OUT_OF_BOUND; + } + + for(unsigned int i = index; i < m_unLen - 1; i++) + m_pbtContent[i] = m_pbtContent[i + 1]; + + m_unLen--; +} + +void UUCByteArray::removeAll() { + memset(m_pbtContent,0, m_nCapacity); + m_unLen = 0; +} + +long UUCByteArray::append(const BYTE btVal) { + if(m_unLen == m_nCapacity) { + m_nCapacity += DEFAULT_CAPACITY; + BYTE* buffer = (BYTE*)realloc(m_pbtContent, m_nCapacity); + if(buffer == NULL) + return ERROR_UNABLE_TO_ALLOCATE; + + m_pbtContent = buffer; + } + + m_pbtContent[m_unLen] = btVal; + + m_unLen++; + + return S_OK; +} + +long UUCByteArray::append(const BYTE* pbtVal, const unsigned long nLen) { + if(m_unLen + nLen > m_nCapacity) { + m_nCapacity += nLen; + BYTE* buffer = (BYTE*)realloc(m_pbtContent, m_nCapacity); + if(buffer == NULL) + return ERROR_UNABLE_TO_ALLOCATE; + + m_pbtContent = buffer; + } + + for(unsigned int i = 0; i < nLen; i++) { + m_pbtContent[m_unLen] = pbtVal[i]; + m_unLen++; + } + + return S_OK; +} + +long UUCByteArray::append(const UUCByteArray& val) { + return append(val.getContent(), val.getLength()); +} + +long UUCByteArray::append(const char* szHexString) { + UUCByteArray ba(szHexString); + return append(ba.getContent(), ba.getLength()); +} + +/* +void UUCByteArray::toHexString(char* szHexString) const +{ + try + { + char szDigit[3]; + strcpy(szHexString, ""); + for(unsigned int i = 0; i < m_unLen; i++) + { + sprintf(szDigit, "%02X", m_pbtContent[i]); + strcat(szHexString, szDigit); + } + } + catch(...) + { + throw new UUCException("UUCByteArray:toHexString:Access Violation"); + } +} +*/ + +long UUCByteArray::reverse() { + BYTE* pbtContent = (BYTE*)malloc(m_unLen); + if(pbtContent == NULL) + return ERROR_UNABLE_TO_ALLOCATE; + + for(int i = 0; i < m_unLen; i++) { + pbtContent[i] = m_pbtContent[m_unLen - i - 1]; + } + + memcpy(m_pbtContent, pbtContent, m_unLen); + + free(pbtContent); + + return S_OK; +} + +const char* UUCByteArray::toHexString() { + return toHexString(0); +} + +const char* UUCByteArray::toHexString(int nSize) { + if(m_szHex) { + delete m_szHex; + m_szHex = NULL; + } + + if(nSize == 0 || nSize > m_unLen) { + nSize = (int)m_unLen; + } + + m_szHex = new char[(nSize + 1) * 2]; + + try { + char szDigit[3]; + memset(m_szHex, 0, (nSize + 1) * 2); + for(unsigned int i = 0; i < nSize; i++) { + snprintf(szDigit, 3, "%02X", m_pbtContent[i]); + strncat(m_szHex, szDigit, 2); + } + + return m_szHex; + } catch(...) { + delete m_szHex; + m_szHex = NULL; + throw -3L; + } + + +} + +int atox(const char* szVal) { + int nVal = 0; + + if(szVal[1] >='0' && szVal[1] <= '9') { + nVal = szVal[1] - '0'; + } else if(szVal[1] >='a' && szVal[1] <= 'f') { + nVal = szVal[1] - 'a' + 10; + } else if(szVal[1] >='A' && szVal[1] <= 'F') { + nVal = szVal[1] - 'A' + 10; + } else { + throw(-1); + } + + + if(szVal[0] >='0' && szVal[0] <= '9') { + nVal += (szVal[0] - '0') * 16; + } else if(szVal[0] >='a' && szVal[0] <= 'f') { + nVal += (szVal[0] - 'a' + 10) * 16; + } else if(szVal[0] >='A' && szVal[0] <= 'F') { + nVal += (szVal[0] - 'A' + 10) * 16; + } else { + throw(-1); + } + + return nVal; +} diff --git a/libcie-pkcs11/Util/UUCProperties.cpp b/libcie-pkcs11/Util/UUCProperties.cpp index 2ea0a14a..bdd61d37 100644 --- a/libcie-pkcs11/Util/UUCProperties.cpp +++ b/libcie-pkcs11/Util/UUCProperties.cpp @@ -1,168 +1,168 @@ -/* UUCProperties.cpp: implementation of the UUCProperties class. -* -* Copyright (c) 2000-2018 by Ugo Chirico - http://www.ugochirico.com -* All Rights Reserved -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU Lesser General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "UUCProperties.h" -#include "UUCTextFileReader.h" -#include - -#include - -#ifdef WIN32 -#define TZSET _tzset -#else -#define TZSET tzset -#endif - -#define SAFEDELETE(pointer) try { if(pointer) { delete pointer; pointer = NULL;}} catch(...) {} - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -#define MAX_ALLOC_SIZE 512 - -UUCProperties::UUCProperties() { - m_pStringTable = new UUCStringTable(); - m_bAllocated = true; -} - -UUCProperties::UUCProperties(const UUCProperties& defaults) - : m_pStringTable(defaults.m_pStringTable) { - m_bAllocated = false; -} - -UUCProperties::~UUCProperties() { - if(m_bAllocated) - SAFEDELETE(m_pStringTable); - - m_pStringTable = NULL; -} - -long UUCProperties::load(const char* szFilePath) { - try { - UUCTextFileReader textFileReader(szFilePath); - - char* szName; - char* szValue; - - long nEOF = -1; - - UUCByteArray line; - long nRes = textFileReader.readLine(line); - - char* szLine = (char*)line.getContent(); - char* szSavePtr; - - while(nRes != nEOF) { - if(szLine[0] != '#' && szLine[0] != '[') { // salta i commenti - szName = strtok_r(szLine, "=", &szSavePtr); - szValue = strtok_r(NULL, "\n", &szSavePtr); - putProperty(szName, szValue); - } - - line.removeAll(); - nRes = textFileReader.readLine(line); - szLine = (char*)line.getContent(); - } - } catch(long nErr) { - return nErr; - } catch(...) { -#ifdef WIN32 - return GetLastError(); -#else - return -1; -#endif - } - - return 0; -} - -long UUCProperties::load(const UUCByteArray& props) { - char* szName; - char* szValue; - char* szEqual; - char* szSavePtr; - char* szProps = (char*)props.getContent(); - char* szLine = strtok_r(szProps, "\r\n", &szSavePtr); - - while(szLine) { - if(szLine[0] != '#' && szLine[0] != '[') { // salta i commenti - szEqual = strstr(szLine, "="); - szEqual[0] = 0; - szName = szLine; - szValue = szEqual + 1; - putProperty(szName, szValue); - szLine = strtok_r(NULL, "\r\n", &szSavePtr); - } else { - szLine = strtok_r(NULL, "\r\n", &szSavePtr);//strlen(szLine) + 1; - //szProps += strlen(szLine) + 1; - } - } - - return 0; -} - - - -int UUCProperties::getIntProperty(const char* szName, int nDefaultValue /*= NULL*/) const { - - const char* szVal = getProperty(szName, NULL); - if(szVal) - return strtol(szVal, NULL, 10); - else - return nDefaultValue; -} - -const char* UUCProperties::getProperty(const char* szName, const char* szDefaultValue /*= NULL*/) const { - char* szValue; - char* szName1 = (char*)szName; - if(m_pStringTable->containsKey(szName1)) { - m_pStringTable->get(szName1, szValue); - return szValue; - } else { - return szDefaultValue; - } -} - -void UUCProperties::putProperty(const char* szName, const char* szValue) { - m_pStringTable->put((char*)szName, (char*)szValue); -} - -UUCStringTable* UUCProperties::getPropertyTable() const { - return m_pStringTable; -} - -bool UUCProperties::contains(const char* szName) const { - return m_pStringTable->containsKey((char*)szName); -} - - - -void UUCProperties::remove(const char *szName) { - m_pStringTable->remove((char*)szName); -} - -void UUCProperties::removeAll() { - m_pStringTable->removeAll(); -} - -int UUCProperties::size() const { - return m_pStringTable->size(); -} +/* UUCProperties.cpp: implementation of the UUCProperties class. +* +* Copyright (c) 2000-2018 by Ugo Chirico - http://www.ugochirico.com +* All Rights Reserved +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "UUCProperties.h" +#include "UUCTextFileReader.h" +#include + +#include + +#ifdef WIN32 +#define TZSET _tzset +#else +#define TZSET tzset +#endif + +#define SAFEDELETE(pointer) try { if(pointer) { delete pointer; pointer = NULL;}} catch(...) {} + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +#define MAX_ALLOC_SIZE 512 + +UUCProperties::UUCProperties() { + m_pStringTable = new UUCStringTable(); + m_bAllocated = true; +} + +UUCProperties::UUCProperties(const UUCProperties& defaults) + : m_pStringTable(defaults.m_pStringTable) { + m_bAllocated = false; +} + +UUCProperties::~UUCProperties() { + if(m_bAllocated) + SAFEDELETE(m_pStringTable); + + m_pStringTable = NULL; +} + +long UUCProperties::load(const char* szFilePath) { + try { + UUCTextFileReader textFileReader(szFilePath); + + char* szName; + char* szValue; + + long nEOF = -1; + + UUCByteArray line; + long nRes = textFileReader.readLine(line); + + char* szLine = (char*)line.getContent(); + char* szSavePtr; + + while(nRes != nEOF) { + if(szLine[0] != '#' && szLine[0] != '[') { // salta i commenti + szName = strtok_r(szLine, "=", &szSavePtr); + szValue = strtok_r(NULL, "\n", &szSavePtr); + putProperty(szName, szValue); + } + + line.removeAll(); + nRes = textFileReader.readLine(line); + szLine = (char*)line.getContent(); + } + } catch(long nErr) { + return nErr; + } catch(...) { +#ifdef WIN32 + return GetLastError(); +#else + return -1; +#endif + } + + return 0; +} + +long UUCProperties::load(const UUCByteArray& props) { + char* szName; + char* szValue; + char* szEqual; + char* szSavePtr; + char* szProps = (char*)props.getContent(); + char* szLine = strtok_r(szProps, "\r\n", &szSavePtr); + + while(szLine) { + if(szLine[0] != '#' && szLine[0] != '[') { // salta i commenti + szEqual = strstr(szLine, "="); + szEqual[0] = 0; + szName = szLine; + szValue = szEqual + 1; + putProperty(szName, szValue); + szLine = strtok_r(NULL, "\r\n", &szSavePtr); + } else { + szLine = strtok_r(NULL, "\r\n", &szSavePtr);//strlen(szLine) + 1; + //szProps += strlen(szLine) + 1; + } + } + + return 0; +} + + + +int UUCProperties::getIntProperty(const char* szName, int nDefaultValue /*= NULL*/) const { + + const char* szVal = getProperty(szName, NULL); + if(szVal) + return strtol(szVal, NULL, 10); + else + return nDefaultValue; +} + +const char* UUCProperties::getProperty(const char* szName, const char* szDefaultValue /*= NULL*/) const { + char* szValue; + char* szName1 = (char*)szName; + if(m_pStringTable->containsKey(szName1)) { + m_pStringTable->get(szName1, szValue); + return szValue; + } else { + return szDefaultValue; + } +} + +void UUCProperties::putProperty(const char* szName, const char* szValue) { + m_pStringTable->put((char*)szName, (char*)szValue); +} + +UUCStringTable* UUCProperties::getPropertyTable() const { + return m_pStringTable; +} + +bool UUCProperties::contains(const char* szName) const { + return m_pStringTable->containsKey((char*)szName); +} + + + +void UUCProperties::remove(const char *szName) { + m_pStringTable->remove((char*)szName); +} + +void UUCProperties::removeAll() { + m_pStringTable->removeAll(); +} + +int UUCProperties::size() const { + return m_pStringTable->size(); +} diff --git a/libcie-pkcs11/Util/UUCStringTable.cpp b/libcie-pkcs11/Util/UUCStringTable.cpp index e33a9d9e..d1100606 100644 --- a/libcie-pkcs11/Util/UUCStringTable.cpp +++ b/libcie-pkcs11/Util/UUCStringTable.cpp @@ -1,116 +1,116 @@ -/* UUCStringTable.cpp: implementation of the UUCStringTable class. -* -* Copyright (c) 2000-2018 by Ugo Chirico - http://www.ugochirico.com -* All Rights Reserved -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU Lesser General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "UUCStringTable.h" -#include -#include -#include - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -UUCStringTable::UUCStringTable(int initialCapacity, float loadFactor) - : UUCHashtable(initialCapacity, loadFactor) { - -} - -UUCStringTable::UUCStringTable(int initialCapacity) - : UUCHashtable(initialCapacity) { - -} - -UUCStringTable::UUCStringTable() { - -} - - -UUCStringTable::~UUCStringTable() { - removeAll(); -} - -void UUCStringTable::put(char* const& szKey, char* const& szValue) { - char* szOldValue = NULL; - char* szOldKey = szKey; - - if(containsKey(szKey)) { - get(szOldKey, szOldValue); - } else { - szOldKey = NULL; - } - - std::string sNewValue(szValue); - std::string sNewKey(szKey); - - UUCHashtable::put((char*)sNewKey.c_str(), (char*)sNewValue.c_str()); - - if(szOldKey) - delete szOldKey; - if(szOldValue) - delete szOldValue; -} - -unsigned long UUCStringTable::getHashValue(char* const& szKey) const { - return UUCStringTable::getHash((const char*)szKey); -} - -unsigned long UUCStringTable::getHash(const char* szKey) { - int h = 0; - int off = 0; - char* val = (char*)szKey; - std::string sKey(szKey); - size_t len = sKey.size(); - - if (len < 16) { - for (unsigned long i = len ; i > 0; i--) { - h = (h * 37) + val[off++]; - } - } else { - // only sample some characters - unsigned long skip = len / 8; - for (int i = len ; i > 0; i -= skip, off += skip) { - h = (h * 39) + val[off]; - } - } - - return h; -} - -bool UUCStringTable::equal(char* const& szKey1, char* const& szKey2) const { - return strcmp(szKey1,szKey2) == 0; -} - -bool UUCStringTable::remove(char* const& szKey) { - char* szNewValue; - - char* szNewKey = szKey;; - - if(containsKey(szKey)) { - get(szNewKey, szNewValue); - - UUCHashtable::remove(szNewKey); - - delete szNewKey; - delete szNewValue; - return true; - } - - return false; -} +/* UUCStringTable.cpp: implementation of the UUCStringTable class. +* +* Copyright (c) 2000-2018 by Ugo Chirico - http://www.ugochirico.com +* All Rights Reserved +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "UUCStringTable.h" +#include +#include +#include + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +UUCStringTable::UUCStringTable(int initialCapacity, float loadFactor) + : UUCHashtable(initialCapacity, loadFactor) { + +} + +UUCStringTable::UUCStringTable(int initialCapacity) + : UUCHashtable(initialCapacity) { + +} + +UUCStringTable::UUCStringTable() { + +} + + +UUCStringTable::~UUCStringTable() { + removeAll(); +} + +void UUCStringTable::put(char* const& szKey, char* const& szValue) { + char* szOldValue = NULL; + char* szOldKey = szKey; + + if(containsKey(szKey)) { + get(szOldKey, szOldValue); + } else { + szOldKey = NULL; + } + + std::string sNewValue(szValue); + std::string sNewKey(szKey); + + UUCHashtable::put((char*)sNewKey.c_str(), (char*)sNewValue.c_str()); + + if(szOldKey) + delete szOldKey; + if(szOldValue) + delete szOldValue; +} + +unsigned long UUCStringTable::getHashValue(char* const& szKey) const { + return UUCStringTable::getHash((const char*)szKey); +} + +unsigned long UUCStringTable::getHash(const char* szKey) { + int h = 0; + int off = 0; + char* val = (char*)szKey; + std::string sKey(szKey); + size_t len = sKey.size(); + + if (len < 16) { + for (unsigned long i = len ; i > 0; i--) { + h = (h * 37) + val[off++]; + } + } else { + // only sample some characters + unsigned long skip = len / 8; + for (int i = len ; i > 0; i -= skip, off += skip) { + h = (h * 39) + val[off]; + } + } + + return h; +} + +bool UUCStringTable::equal(char* const& szKey1, char* const& szKey2) const { + return strcmp(szKey1,szKey2) == 0; +} + +bool UUCStringTable::remove(char* const& szKey) { + char* szNewValue; + + char* szNewKey = szKey;; + + if(containsKey(szKey)) { + get(szNewKey, szNewValue); + + UUCHashtable::remove(szNewKey); + + delete szNewKey; + delete szNewValue; + return true; + } + + return false; +} diff --git a/libcie-pkcs11/Util/UUCTextFileReader.cpp b/libcie-pkcs11/Util/UUCTextFileReader.cpp index f0a5b367..a5f7d607 100644 --- a/libcie-pkcs11/Util/UUCTextFileReader.cpp +++ b/libcie-pkcs11/Util/UUCTextFileReader.cpp @@ -1,112 +1,112 @@ -/* UUCTextFile.cpp: implementation of the UUCTextFile class. - * - * Copyright (c) 2000-2018 by Ugo Chirico - http://www.ugochirico.com - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "UUCTextFileReader.h" -#include -#include - - - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -UUCTextFileReader::UUCTextFileReader(const char* szFilePath) { - //LOG_DBG((0, "UUCTextFileReader", szFilePath)); - m_pf = fopen(szFilePath, "rt"); - if(!m_pf) { - //LOG_DBG((0, "UUCTextFileReader", "fopen not found: %s", szFilePath )); - throw (long)ERROR_FILE_NOT_FOUND; - } - - struct stat lstat_buf; - struct stat fstat_buf; - - int r = lstat(szFilePath, &lstat_buf); - - /* handle the case of the lstat failing first */ - if (r == -1) { - fclose(m_pf); - throw (long)ERROR_FILE_NOT_FOUND; - } - - if (S_ISLNK(lstat_buf.st_mode)) { - fclose(m_pf); - throw (long)ERROR_FILE_NOT_FOUND; - } - - /* Get the properties of the opened file descriptor */ - r = stat(szFilePath, &fstat_buf); - if (r == -1) { - fclose(m_pf); - throw (long)ERROR_FILE_NOT_FOUND; - } - - if (lstat_buf.st_dev != fstat_buf.st_dev - || lstat_buf.st_ino != fstat_buf.st_ino - || (S_IFMT & lstat_buf.st_mode) != (S_IFMT & fstat_buf.st_mode)) { - fclose(m_pf); - throw (long)ERROR_FILE_NOT_FOUND; - } - //LOG_DBG((0, "UUCTextFileReader", "read OK %s", szFilePath)); -} - -UUCTextFileReader::~UUCTextFileReader() { - fclose(m_pf); -} - -long UUCTextFileReader::readLine(UUCByteArray& line) { - char szLine[2]; - unsigned int i = 0; - while((fread(szLine, 1, 1, m_pf) > 0) && (szLine[0] != '\n') ) { - i++; - line.append(szLine[0]); - } - - if(i > 0) { - line.append((BYTE)0); - return 0; - } else if((i == 0) && szLine[0] == '\n') { - return readLine(line); - } else { - return -1; - } -} - -long UUCTextFileReader::readLine(char* szLine, unsigned long nLen) { // throw (long) - unsigned int i = 0; - while((fread(szLine + i, 1, 1, m_pf) > 0) && (szLine[i] != '\n') ) { - i++; - if(i == nLen) { - //SetLastError(ERROR_MORE_DATA); - throw (long)ERROR_MORE_DATA; - } - } - - if(i > 0) { - szLine[i] = 0; - return 0; - } else if((i == 0) && szLine[i] == '\n') { - return readLine(szLine, nLen); - } else { - return -1; - } -} - +/* UUCTextFile.cpp: implementation of the UUCTextFile class. + * + * Copyright (c) 2000-2018 by Ugo Chirico - http://www.ugochirico.com + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "UUCTextFileReader.h" +#include +#include + + + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +UUCTextFileReader::UUCTextFileReader(const char* szFilePath) { + //LOG_DBG((0, "UUCTextFileReader", szFilePath)); + m_pf = fopen(szFilePath, "rt"); + if(!m_pf) { + //LOG_DBG((0, "UUCTextFileReader", "fopen not found: %s", szFilePath )); + throw (long)ERROR_FILE_NOT_FOUND; + } + + struct stat lstat_buf; + struct stat fstat_buf; + + int r = lstat(szFilePath, &lstat_buf); + + /* handle the case of the lstat failing first */ + if (r == -1) { + fclose(m_pf); + throw (long)ERROR_FILE_NOT_FOUND; + } + + if (S_ISLNK(lstat_buf.st_mode)) { + fclose(m_pf); + throw (long)ERROR_FILE_NOT_FOUND; + } + + /* Get the properties of the opened file descriptor */ + r = stat(szFilePath, &fstat_buf); + if (r == -1) { + fclose(m_pf); + throw (long)ERROR_FILE_NOT_FOUND; + } + + if (lstat_buf.st_dev != fstat_buf.st_dev + || lstat_buf.st_ino != fstat_buf.st_ino + || (S_IFMT & lstat_buf.st_mode) != (S_IFMT & fstat_buf.st_mode)) { + fclose(m_pf); + throw (long)ERROR_FILE_NOT_FOUND; + } + //LOG_DBG((0, "UUCTextFileReader", "read OK %s", szFilePath)); +} + +UUCTextFileReader::~UUCTextFileReader() { + fclose(m_pf); +} + +long UUCTextFileReader::readLine(UUCByteArray& line) { + char szLine[2]; + unsigned int i = 0; + while((fread(szLine, 1, 1, m_pf) > 0) && (szLine[0] != '\n') ) { + i++; + line.append(szLine[0]); + } + + if(i > 0) { + line.append((BYTE)0); + return 0; + } else if((i == 0) && szLine[0] == '\n') { + return readLine(line); + } else { + return -1; + } +} + +long UUCTextFileReader::readLine(char* szLine, unsigned long nLen) { // throw (long) + unsigned int i = 0; + while((fread(szLine + i, 1, 1, m_pf) > 0) && (szLine[i] != '\n') ) { + i++; + if(i == nLen) { + //SetLastError(ERROR_MORE_DATA); + throw (long)ERROR_MORE_DATA; + } + } + + if(i > 0) { + szLine[i] = 0; + return 0; + } else if((i == 0) && szLine[i] == '\n') { + return readLine(szLine, nLen); + } else { + return -1; + } +} + diff --git a/libcie-pkcs11/Util/UtilException.cpp b/libcie-pkcs11/Util/UtilException.cpp index 1bd0a7e2..40d1628d 100644 --- a/libcie-pkcs11/Util/UtilException.cpp +++ b/libcie-pkcs11/Util/UtilException.cpp @@ -2,7 +2,9 @@ #include #include "UtilException.h" #include "util.h" +#include "../LOGGER/Logger.h" +using namespace CieIDLogger; logged_error::logged_error(std::string message) : std::runtime_error(message.c_str()) { @@ -10,7 +12,7 @@ logged_error::logged_error(std::string message) } logged_error::logged_error(const char *message) : std::runtime_error(message) { - OutputDebugString("%s", what()); + LOG_ERROR("%s", message); } scard_error::scard_error(StatusWord sw) : logged_error(stdPrintf("Errore smart card:%x", sw)) { } diff --git a/libcie-pkcs11/Util/funccallinfo.cpp b/libcie-pkcs11/Util/funccallinfo.cpp index 5af50495..befabefc 100644 --- a/libcie-pkcs11/Util/funccallinfo.cpp +++ b/libcie-pkcs11/Util/funccallinfo.cpp @@ -1,49 +1,48 @@ - -#include "funccallinfo.h" -#include - -thread_local size_t tlsCallDepth = 0; -thread_local std::unique_ptr callQueue = nullptr; -extern bool FunctionLog; -extern unsigned int GlobalDepth; -extern bool GlobalParam; -char szEmpty[]= {'\0'}; - -CFuncCallInfo::CFuncCallInfo(const char *name, CLog &logInfo) : log(logInfo) { - fName = name; - //OutputDebugString("%s", fName); - if (FunctionLog) { - if (tlsCallDepth < GlobalDepth) { - LogNum = logInfo.write("%*sIN -> %s", (DWORD)tlsCallDepth, szEmpty, fName); - } - } - - //fName = name; - tlsCallDepth = tlsCallDepth + 1; - - -// auto head = callQueue.release(); -// callQueue = std::unique_ptr(new CFuncCallInfoList(this)); -// callQueue->next = std::unique_ptr(head); -} - -CFuncCallInfo::~CFuncCallInfo() { - //OutputDebugString("%s", stdPrintf("OUT %s", fName).c_str()); - //fName = NULL; - tlsCallDepth=tlsCallDepth-1; - if (fName) - log.write("%*sOUT -> %s (%u)",(DWORD)tlsCallDepth,szEmpty,fName,LogNum-1); - -// if (callQueue!=nullptr && callQueue->info == this) { -// //auto head = callQueue->next.release(); -//// callQueue = std::unique_ptr(head); -// } -// else { -// callQueue = nullptr; -// OutputDebugString("%s", "Errore nella sequenza delle funzioni"); -// } -} - -const char *CFuncCallInfo::FunctionName() { - return fName; -} +#include "funccallinfo.h" +#include + +thread_local size_t tlsCallDepth = 0; +thread_local std::unique_ptr callQueue = nullptr; +extern bool FunctionLog; +extern unsigned int GlobalDepth; +extern bool GlobalParam; +char szEmpty[]= {'\0'}; + +CFuncCallInfo::CFuncCallInfo(const char *name, CLog &logInfo) : log(logInfo) { + fName = name; + //OutputDebugString("%s", fName); + if (FunctionLog) { + if (tlsCallDepth < GlobalDepth) { + LogNum = logInfo.write("%*sIN -> %s", (DWORD)tlsCallDepth, szEmpty, fName); + } + } + + //fName = name; + tlsCallDepth = tlsCallDepth + 1; + + +// auto head = callQueue.release(); +// callQueue = std::unique_ptr(new CFuncCallInfoList(this)); +// callQueue->next = std::unique_ptr(head); +} + +CFuncCallInfo::~CFuncCallInfo() { + //OutputDebugString("%s", stdPrintf("OUT %s", fName).c_str()); + //fName = NULL; + tlsCallDepth=tlsCallDepth-1; + if (fName) + log.write("%*sOUT -> %s (%u)",(DWORD)tlsCallDepth,szEmpty,fName,LogNum-1); + +// if (callQueue!=nullptr && callQueue->info == this) { +// //auto head = callQueue->next.release(); +//// callQueue = std::unique_ptr(head); +// } +// else { +// callQueue = nullptr; +// OutputDebugString("%s", "Errore nella sequenza delle funzioni"); +// } +} + +const char *CFuncCallInfo::FunctionName() { + return fName; +} \ No newline at end of file diff --git a/libcie-pkcs11/Util/log.cpp b/libcie-pkcs11/Util/log.cpp index c372304d..5e545f01 100644 --- a/libcie-pkcs11/Util/log.cpp +++ b/libcie-pkcs11/Util/log.cpp @@ -1,498 +1,500 @@ - -#define __STDC_WANT_LIB_EXT1__ 1 - -#include -#include "util.h" -#include "ModuleInfo.h" -#include -#include -#include -#include "log.h" -#include "UtilException.h" -//#include "Thread.h" -#include "IniSettings.h" -#include -#include -#include -#include "UUCProperties.h" -#include -#include -#include -#include -#include - -std::string globalLogDir; -std::string globalLogName; -bool FunctionLog=false; -bool globalLogParam=false; -bool firstGlobal=false; -const char *logGlobalVersion; -unsigned int GlobalDepth = 0; -bool mainInit=false; -bool mainEnable=false; -unsigned int GlobalCount; - -enum logMode { - LM_Single, // un solo file - LM_Module, // un file per modulo - LM_Thread, // un file per thread - LM_Module_Thread // un file per modulo e per thread -} LogMode = LM_Module; - - -void initLog(const char *moduleName, const char *iniFile,const char *version) { - - if (mainInit) - return; - - mainInit=true; - - logGlobalVersion=version; - - OutputDebugString("%s", "File INI:"); - OutputDebugString("%s", iniFile); - OutputDebugString("%s", "\n"); - - UUCProperties settings; - //settings.load(iniFile); - - LogMode = (logMode)(settings.getIntProperty("LogMode", (int)LM_Single));//, "Modalità di Log. Valori possibili:\n" -// "0 ;LM_Single, // un solo file\n" -// "1 ;LM_Module, // un file per modulo\n" -// "2 ;LM_Thread, // un file per thread\n" -// "3 ;LM_Module_Thread // un file per modulo e per thread\n")).GetValue((char*)iniFile); - - if (LogMode == -1) { - LogMode=LM_Single; - } - - mainEnable = settings.getIntProperty("LogEnable",1);//,"Abilitazione log globale")).GetValue((char*)iniFile); - - FunctionLog = settings.getIntProperty("FunctionLog", 1);//, "Abilitazione log delle chiamate a funzione")).GetValue((char*)iniFile); - - GlobalDepth = settings.getIntProperty("FunctionDepth", 10);//, "Definisce la profondità massima di log delle funzioni\n")).GetValue((char*)iniFile); - - globalLogParam = settings.getIntProperty("ParamLog", 1);//, "Abilitazione log dei parametri di input delle funzioni")).GetValue((char*)iniFile); - - globalLogName = moduleName; - - char* home = getenv("HOME"); - if(home == NULL) { - struct passwd *pw = getpwuid(getuid()); - - home = pw->pw_dir; - printf("home: %s", home); - } - - std::string path(home); - - path.append("/.CIEPKI/"); - - struct stat st = {0}; - - if (stat(path.c_str(), &st) == -1) { - mkdir(path.c_str(), 0700); - } - - globalLogDir = settings.getProperty("LogDir", path.c_str()); //"Definisce il path in cui salvare il file di log (con / finale)")) - -} - -CLog::CLog() { - - init(); -} - -CLog::~CLog() { - Enabled=false; - FirstLog=false; -} - -void CLog::init() { - - Enabled=mainEnable; - LogParam=globalLogParam; - LogCount=0; - logName = globalLogName; - logFileName = globalLogName; - - std::stringstream th; - th << std::setw(8) << std::setfill('0'); - - time_t T= time(NULL); - struct tm t; - struct tm tm = *localtime_r(&T, &t); - - switch (LogMode) { - case (LM_Single): { - th << logFileName << "_" << std::setw(4) << tm.tm_year << "-" << std::setw(2) << tm.tm_mon << "-" << tm.tm_mday << ".log"; - break; - } - case (LM_Module): { - th << std::setw(4) << tm.tm_year << "-" << std::setw(2) << tm.tm_mon << "-" << tm.tm_mday << "_" << logFileName << ".log"; - // log per modulo: il nome del file è yyyy-mm-gg_name.log, senza alcun path assegnato - break; - } - case (LM_Thread): { - th << std::setw(4) << tm.tm_year << "-" << std::setw(2) << tm.tm_mon << "-" << tm.tm_mday << "_00000000.log"; - // log per thread: il nome del file è yyyy-mm-gg_tttttttt.log, senza alcun path assegnato - break; - } - case (LM_Module_Thread): { - th << std::setw(4) << tm.tm_year << "-" << std::setw(2) << tm.tm_mon << "-" << tm.tm_mday << "_" << logFileName << "_00000000.log"; - // log per modulo e per thread: il nome del file è yyyy-mm-gg_name_tttttttt.log, senza alcun path assegnato - break; - } - } - - logPath = th.str(); - - if ((LogMode==LM_Module || LogMode==LM_Module_Thread) && logDir.length()!=0) { - // se c'è un path specifico lo metto lì - std::string path = logPath; - logPath=logDir.append(path); - } else if (!globalLogDir.empty()) { - // se c'è un path globale lo metto lì - std::string path=logPath; - logPath = globalLogDir.append(path); - } - threadPos = logPath.begin()+logPath.length() - 12; - Initialized=true; - - if (LogMode!=LM_Module && LogMode!=LM_Module_Thread && Enabled) writePure("Module %02i: %s",ModuleNum,logName.c_str()); - -} - -DWORD CLog::write(const char *format,...) { - va_list params; - va_start (params, format); - char pbtDate[20]; - unsigned int dummy = 0; - unsigned int *Num = &dummy; - - if (Enabled && Initialized && mainEnable) { - - if (!firstGlobal && LogMode==LM_Single) { - firstGlobal =true; - write("Inizio Sessione - versione: %s",logGlobalVersion); - writeModuleInfo(); - } - if (!FirstLog && (LogMode==LM_Module || LogMode==LM_Module_Thread)) { - FirstLog=true; - write("%s - Inizio Sessione - versione file: %s",logName.c_str(), logVersion.c_str()); - writeModuleInfo(); - } - - //DWORD thNum; - switch(LogMode) { - case (LM_Module) : - Num=&LogCount; - break; - case (LM_Module_Thread) : - case (LM_Thread) : /*thNum=dwThreadCount;dwNum=&thNum;0*/ - break; - case (LM_Single) : - Num=&GlobalCount; - break; - } -#ifdef WIN32 - SYSTEMTIME stTime; - GetLocalTime(&stTime); - sprintf_s(pbtDate,sizeof(pbtDate),"%05u:[%02d:%02d:%02d.%03d]", *Num, stTime.wHour, stTime.wMinute, stTime.wSecond, stTime.wMilliseconds); -#else - time_t T= time(NULL); - struct tm t; - struct tm tm = *localtime_r(&T, &t); - - snprintf(pbtDate,20,"%05u:[%02d:%02d:0%02d]", *Num, tm.tm_hour, tm.tm_min, tm.tm_sec); -#endif - // se siamo in LM_thread devo scrivere il thread nel nome del file - std::hash hasher; - auto dwThreadID = hasher(std::this_thread::get_id()); - if (LogMode == LM_Thread || LogMode == LM_Module_Thread) { - std::stringstream th; - th << std::setiosflags(std::ios::hex | std::ios::uppercase); - th << std::setw(8); - th << dwThreadID << ".log"; - - logPath.replace(threadPos, threadPos + 14, th.str()); - } - FILE *lf=nullptr; -#ifdef WIN32 - fopen_s(&lf,logPath.c_str(), "a+t"); - if (lf) { - switch(LogMode) { - case (LM_Single) : - case (LM_Single) : - fprintf(lf,"%s|%04i|%04i|%02i|", pbtDate, getpid(), dwThreadID, ModuleNum); - break; - break; - case (LM_Module) : - fprintf(lf,"%s|%04i|%04x|", pbtDate, GetCurrentProcessId(), dwThreadID); - break; - case (LM_Thread) : - fprintf(lf,"%s|%04i|%02i|", pbtDate, GetCurrentProcessId(), ModuleNum); - break; - case (LM_Module_Thread) : - fprintf(lf,"%s|", pbtDate); - break; - } - vfprintf(lf, format, params); - fprintf(lf, "\n"); - fclose(lf); - } -#else - lf = fopen(logPath.c_str(), "a+t"); - if (lf) { - - struct stat lstat_buf; - struct stat fstat_buf; - - int r = lstat(logPath.c_str(), &lstat_buf); - - /* handle the case of the lstat failing first */ - if (r == -1) { - fclose(lf); - return ERROR_FILE_NOT_FOUND; - } - - if (S_ISLNK(lstat_buf.st_mode)) { - fclose(lf); - return (long)ERROR_FILE_NOT_FOUND; - } - - /* Get the properties of the opened file descriptor */ - r = stat(logPath.c_str(), &fstat_buf); - if (r == -1) { - fclose(lf); - return (long)ERROR_FILE_NOT_FOUND; - } - - if (lstat_buf.st_dev != fstat_buf.st_dev - || lstat_buf.st_ino != fstat_buf.st_ino - || (S_IFMT & lstat_buf.st_mode) != (S_IFMT & fstat_buf.st_mode)) { - fclose(lf); - return (long)ERROR_FILE_NOT_FOUND; - } - - switch(LogMode) { - case (LM_Single) : - fprintf(lf,"%s|%04i|%04lx|%02i|", pbtDate, getpid(), dwThreadID, ModuleNum); - break; - case (LM_Module) : - fprintf(lf,"%s|%04i|%04lx|", pbtDate, getpid(), dwThreadID); - break; - case (LM_Thread) : - fprintf(lf,"%s|%04i|%02i|", pbtDate, getpid(), ModuleNum); - break; - case (LM_Module_Thread) : - fprintf(lf,"%s|", pbtDate); - break; - } - vfprintf(lf, format, params); - fprintf(lf, "\n"); - fclose(lf); - } - -// printf(format, params); -// printf("\n", NULL); -#endif - - } - -#ifdef _DEBUG -#ifdef WIN32 - vsprintf_s(pbtDate, format, params); - int dtLen = (int)strnlen(pbtDate, sizeof(pbtDate)); - sprintf_s(pbtDate + dtLen, 2048 - dtLen, "|thread:%08x|%s|", GetCurrentThreadId(), logName.c_str()); - dtLen = (int)strnlen(pbtDate, sizeof(pbtDate)); - sprintf_s(pbtDate+ dtLen, 2048 - dtLen, "\n"); - OutputDebugString("%s", pbtDate); -#else - puts(pbtDate); -#endif -#endif - va_end(params); - switch(LogMode) { - case (LM_Module) : - LogCount++; - break; - case (LM_Module_Thread) : - case (LM_Thread) : /*dwThreadCount=thNum+1;*/ - break; - case (LM_Single) : - GlobalCount++; - break; - } - return(*Num); -} - -void CLog::writePure(const char *format,...) { - va_list params; - va_start (params, format); -// char pbtDate[0x800]={NULL}; - if (Enabled && Initialized && mainEnable) { - if (!firstGlobal && LogMode==LM_Single) { - firstGlobal =true; - write("Inizio Sessione - versione: %s",logGlobalVersion); - writeModuleInfo(); - } - if (!FirstLog && (LogMode==LM_Module || LogMode==LM_Module_Thread)) { - FirstLog=true; - write("%s - Inizio Sessione - versione file: %s",logName.c_str(), logVersion.c_str()); - writeModuleInfo(); - } - - // se siamo in LM_thread devo scrivere il thread nel nome del file - std::hash hasher; - auto dwThreadID = hasher(std::this_thread::get_id()); - if (LogMode == LM_Thread || LogMode == LM_Module_Thread) { - std::stringstream th; - th << std::setiosflags(std::ios::hex | std::ios::uppercase); - th << std::setw(8); - th << dwThreadID << ".log"; - - logPath.replace(threadPos, threadPos + 14, th.str()); - } - FILE *lf = nullptr; -#ifdef WIN32 - fopen_s(&lf,logPath.c_str(), "a+t"); -#else - lf = fopen(logPath.c_str(), "a+t"); -#endif - if (lf) { - - struct stat lstat_buf; - struct stat fstat_buf; - - int r = lstat(logPath.c_str(), &lstat_buf); - - /* handle the case of the lstat failing first */ - if (r == -1) { - fclose(lf); - return; - } - - if (S_ISLNK(lstat_buf.st_mode)) { - fclose(lf); - return; - } - - /* Get the properties of the opened file descriptor */ - r = stat(logPath.c_str(), &fstat_buf); - if (r == -1) { - fclose(lf); - return; - } - - if (lstat_buf.st_dev != fstat_buf.st_dev - || lstat_buf.st_ino != fstat_buf.st_ino - || (S_IFMT & lstat_buf.st_mode) != (S_IFMT & fstat_buf.st_mode)) { - fclose(lf); - return; - } - - vfprintf(lf, format, params); - fprintf(lf, "\n"); - fclose(lf); - } - -// printf(format, params); -// printf("\n", NULL); - } -#ifdef _DEBUG -#ifdef WIN32 - int dtLen = (int)strnlen(pbtDate, sizeof(pbtDate)); - vsprintf_s(pbtDate+dtLen,2048-dtLen, format, params); - dtLen = (int)strnlen(pbtDate, sizeof(pbtDate)); - sprintf_s(pbtDate + dtLen, 2048 - dtLen, "\n"); - OutputDebugString("%s", pbtDate); -#else - puts(pbtDate); -#endif -#endif - va_end(params); -} - -void CLog::writeBinData(BYTE *data, size_t datalen) { - if (!Enabled || !Initialized || !mainEnable) return; - if (!firstGlobal && LogMode==LM_Single) { - firstGlobal =true; - write("Inizio Sessione - versione: %s",logGlobalVersion); - writeModuleInfo(); - } - if (!FirstLog && (LogMode==LM_Module || LogMode==LM_Module_Thread)) { - FirstLog=true; - write("%s - Inizio Sessione - versione file: %s",logName.c_str(), logVersion.c_str()); - writeModuleInfo(); - } - -// char pbtDate[0x800]={NULL}; - - // se siamo in LM_thread devo scrivere il thread nel nome del file - std::hash hasher; - auto dwThreadID = hasher(std::this_thread::get_id()); - if (LogMode == LM_Thread || LogMode == LM_Module_Thread) { - std::stringstream th; - th << std::setiosflags(std::ios::hex | std::ios::uppercase); - th << std::setw(8); - th << dwThreadID << ".log"; - - logPath.replace(threadPos, threadPos + 14, th.str()); - } - - FILE *lf = nullptr; -#ifdef WIN32 - fopen_s(&lf,logPath.c_str(), "a+t"); -#else - lf = fopen(logPath.c_str(), "a+t"); -#endif - if (lf) { - - struct stat lstat_buf; - struct stat fstat_buf; - - int r = lstat(logPath.c_str(), &lstat_buf); - - /* handle the case of the lstat failing first */ - if (r == -1) { - fclose(lf); - return; - } - - if (S_ISLNK(lstat_buf.st_mode)) { - fclose(lf); - return; - } - - /* Get the properties of the opened file descriptor */ - r = stat(logPath.c_str(), &fstat_buf); - if (r == -1) { - fclose(lf); - return; - } - - if (lstat_buf.st_dev != fstat_buf.st_dev - || lstat_buf.st_ino != fstat_buf.st_ino - || (S_IFMT & lstat_buf.st_mode) != (S_IFMT & fstat_buf.st_mode)) { - fclose(lf); - return; - } - - - if (datalen>100) datalen=100; - for (size_t i=0; i +#include "util.h" +#include "ModuleInfo.h" +#include +#include +#include +#include "log.h" +#include "UtilException.h" +//#include "Thread.h" +#include "IniSettings.h" +#include +#include +#include +#include "UUCProperties.h" +#include +#include +#include +#include +#include + +std::string globalLogDir; +std::string globalLogName; +bool FunctionLog=false; +bool globalLogParam=false; +bool firstGlobal=false; +const char *logGlobalVersion; +unsigned int GlobalDepth = 0; +bool mainInit=false; +bool mainEnable=false; +unsigned int GlobalCount; + +enum logMode { + LM_Single, // un solo file + LM_Module, // un file per modulo + LM_Thread, // un file per thread + LM_Module_Thread // un file per modulo e per thread +} LogMode = LM_Module; + + +void initLog(const char *moduleName, const char *iniFile,const char *version) { + + if (mainInit) + return; + + mainInit=true; + + logGlobalVersion=version; + + OutputDebugString("File INI:"); + OutputDebugString("\n"); + + UUCProperties settings; + //settings.load(iniFile); + + LogMode = (logMode)(settings.getIntProperty("LogMode", (int)LM_Single));//, "Modalità di Log. Valori possibili:\n" +// "0 ;LM_Single, // un solo file\n" +// "1 ;LM_Module, // un file per modulo\n" +// "2 ;LM_Thread, // un file per thread\n" +// "3 ;LM_Module_Thread // un file per modulo e per thread\n")).GetValue((char*)iniFile); + + if (LogMode == -1) { + LogMode=LM_Single; + } + + mainEnable = settings.getIntProperty("LogEnable",1);//,"Abilitazione log globale")).GetValue((char*)iniFile); + + FunctionLog = settings.getIntProperty("FunctionLog", 1);//, "Abilitazione log delle chiamate a funzione")).GetValue((char*)iniFile); + + GlobalDepth = settings.getIntProperty("FunctionDepth", 10);//, "Definisce la profondità massima di log delle funzioni\n")).GetValue((char*)iniFile); + + globalLogParam = settings.getIntProperty("ParamLog", 1);//, "Abilitazione log dei parametri di input delle funzioni")).GetValue((char*)iniFile); + + globalLogName = moduleName; + + char* home = getenv("HOME"); + if(home == NULL) { + struct passwd *pw = getpwuid(getuid()); + + home = pw->pw_dir; + printf("home: %s", home); + } + + std::string path(home); + + path.append("/.CIEPKI/"); + + struct stat st = {0}; + + if (stat(path.c_str(), &st) == -1) { + mkdir(path.c_str(), 0700); + } + + globalLogDir = settings.getProperty("LogDir", path.c_str()); //"Definisce il path in cui salvare il file di log (con / finale)")) + +} + +CLog::CLog() { + + init(); +} + +CLog::~CLog() { + Enabled=false; + FirstLog=false; +} + +void CLog::init() { + + Enabled=mainEnable; + LogParam=globalLogParam; + LogCount=0; + logName = globalLogName; + logFileName = globalLogName; + + std::stringstream th; + th << std::setw(8) << std::setfill('0'); + + time_t T= time(NULL); + struct tm t; + struct tm tm = *localtime_r(&T, &t); + + switch (LogMode) { + case (LM_Single): { + th << logFileName << "_" << std::setw(4) << tm.tm_year << "-" << std::setw(2) << tm.tm_mon << "-" << tm.tm_mday << ".log"; + break; + } + case (LM_Module): { + th << std::setw(4) << tm.tm_year << "-" << std::setw(2) << tm.tm_mon << "-" << tm.tm_mday << "_" << logFileName << ".log"; + // log per modulo: il nome del file è yyyy-mm-gg_name.log, senza alcun path assegnato + break; + } + case (LM_Thread): { + th << std::setw(4) << tm.tm_year << "-" << std::setw(2) << tm.tm_mon << "-" << tm.tm_mday << "_00000000.log"; + // log per thread: il nome del file è yyyy-mm-gg_tttttttt.log, senza alcun path assegnato + break; + } + case (LM_Module_Thread): { + th << std::setw(4) << tm.tm_year << "-" << std::setw(2) << tm.tm_mon << "-" << tm.tm_mday << "_" << logFileName << "_00000000.log"; + // log per modulo e per thread: il nome del file è yyyy-mm-gg_name_tttttttt.log, senza alcun path assegnato + break; + } + } + + logPath = th.str(); + + if ((LogMode==LM_Module || LogMode==LM_Module_Thread) && logDir.length()!=0) { + // se c'è un path specifico lo metto lì + std::string path = logPath; + logPath=logDir.append(path); + } else if (!globalLogDir.empty()) { + // se c'è un path globale lo metto lì + std::string path=logPath; + logPath = globalLogDir.append(path); + } + threadPos = logPath.begin()+logPath.length() - 12; + Initialized=true; + + if (LogMode!=LM_Module && LogMode!=LM_Module_Thread && Enabled) writePure("Module %02i: %s",ModuleNum,logName.c_str()); + +} + +DWORD CLog::write(const char *format,...) { + va_list params; + va_start (params, format); + char pbtDate[20]; + unsigned int dummy = 0; + unsigned int *Num = &dummy; + + if (Enabled && Initialized && mainEnable) { + + if (!firstGlobal && LogMode==LM_Single) { + firstGlobal =true; + write("Inizio Sessione - versione: %s",logGlobalVersion); + writeModuleInfo(); + } + if (!FirstLog && (LogMode==LM_Module || LogMode==LM_Module_Thread)) { + FirstLog=true; + write("%s - Inizio Sessione - versione file: %s",logName.c_str(), logVersion.c_str()); + writeModuleInfo(); + } + + //DWORD thNum; + switch(LogMode) { + case (LM_Module) : + Num=&LogCount; + break; + case (LM_Module_Thread) : + case (LM_Thread) : /*thNum=dwThreadCount;dwNum=&thNum;0*/ + break; + case (LM_Single) : + Num=&GlobalCount; + break; + } +#ifdef WIN32 + SYSTEMTIME stTime; + GetLocalTime(&stTime); + sprintf_s(pbtDate,sizeof(pbtDate),"%05u:[%02d:%02d:%02d.%03d]", *Num, stTime.wHour, stTime.wMinute, stTime.wSecond, stTime.wMilliseconds); +#else + time_t T= time(NULL); + struct tm t; + struct tm tm = *localtime_r(&T, &t); + + snprintf(pbtDate,20,"%05u:[%02d:%02d:0%02d]", *Num, tm.tm_hour, tm.tm_min, tm.tm_sec); +#endif + // se siamo in LM_thread devo scrivere il thread nel nome del file + std::hash hasher; + auto dwThreadID = hasher(std::this_thread::get_id()); + if (LogMode == LM_Thread || LogMode == LM_Module_Thread) { + std::stringstream th; + th << std::setiosflags(std::ios::hex | std::ios::uppercase); + th << std::setw(8); + th << dwThreadID << ".log"; + + logPath.replace(threadPos, threadPos + 14, th.str()); + } + FILE *lf=nullptr; +#ifdef WIN32 + fopen_s(&lf,logPath.c_str(), "a+t"); + if (lf) { + switch(LogMode) { + case (LM_Single) : + case (LM_Single) : + fprintf(lf,"%s|%04i|%04i|%02i|", pbtDate, getpid(), dwThreadID, ModuleNum); + break; + break; + case (LM_Module) : + fprintf(lf,"%s|%04i|%04x|", pbtDate, GetCurrentProcessId(), dwThreadID); + break; + case (LM_Thread) : + fprintf(lf,"%s|%04i|%02i|", pbtDate, GetCurrentProcessId(), ModuleNum); + break; + case (LM_Module_Thread) : + fprintf(lf,"%s|", pbtDate); + break; + } + vfprintf(lf, format, params); + fprintf(lf, "\n"); + fclose(lf); + } +#else + //lf = fopen(logPath.c_str(), "a+t"); + if (lf) { + + struct stat lstat_buf; + struct stat fstat_buf; + + int r = lstat(logPath.c_str(), &lstat_buf); + + /* handle the case of the lstat failing first */ + if (r == -1) { + fclose(lf); + return ERROR_FILE_NOT_FOUND; + } + + if (S_ISLNK(lstat_buf.st_mode)) { + fclose(lf); + return (long)ERROR_FILE_NOT_FOUND; + } + + /* Get the properties of the opened file descriptor */ + r = stat(logPath.c_str(), &fstat_buf); + if (r == -1) { + fclose(lf); + return (long)ERROR_FILE_NOT_FOUND; + } + + if (lstat_buf.st_dev != fstat_buf.st_dev + || lstat_buf.st_ino != fstat_buf.st_ino + || (S_IFMT & lstat_buf.st_mode) != (S_IFMT & fstat_buf.st_mode)) { + fclose(lf); + return (long)ERROR_FILE_NOT_FOUND; + } + + switch(LogMode) { + case (LM_Single) : + fprintf(lf,"%s|%04i|%04lx|%02i|", pbtDate, getpid(), dwThreadID, ModuleNum); + break; + case (LM_Module) : + fprintf(lf,"%s|%04i|%04lx|", pbtDate, getpid(), dwThreadID); + break; + case (LM_Thread) : + fprintf(lf,"%s|%04i|%02i|", pbtDate, getpid(), ModuleNum); + break; + case (LM_Module_Thread) : + fprintf(lf,"%s|", pbtDate); + break; + } + vfprintf(lf, format, params); + fprintf(lf, "\n"); + fclose(lf); + } + +// printf(format, params); +// printf("\n", NULL); +#endif + + } + +#ifdef _DEBUG +#ifdef WIN32 + vsprintf_s(pbtDate, format, params); + int dtLen = (int)strnlen(pbtDate, sizeof(pbtDate)); + sprintf_s(pbtDate + dtLen, 2048 - dtLen, "|thread:%08x|%s|", GetCurrentThreadId(), logName.c_str()); + dtLen = (int)strnlen(pbtDate, sizeof(pbtDate)); + sprintf_s(pbtDate+ dtLen, 2048 - dtLen, "\n"); + OutputDebugString(pbtDate); +#else + puts(pbtDate); +#endif +#endif + va_end(params); + switch(LogMode) { + case (LM_Module) : + LogCount++; + break; + case (LM_Module_Thread) : + case (LM_Thread) : /*dwThreadCount=thNum+1;*/ + break; + case (LM_Single) : + GlobalCount++; + break; + } + return(*Num); +} + +void CLog::writePure(const char *format,...) { + va_list params; + va_start (params, format); +// char pbtDate[0x800]={NULL}; + if (Enabled && Initialized && mainEnable) { + if (!firstGlobal && LogMode==LM_Single) { + firstGlobal =true; + //write("Inizio Sessione - versione: %s",logGlobalVersion); + printf("Inizio Sessione - versione: %s",logGlobalVersion); + writeModuleInfo(); + } + if (!FirstLog && (LogMode==LM_Module || LogMode==LM_Module_Thread)) { + FirstLog=true; + //write("%s - Inizio Sessione - versione file: %s",logName.c_str(), logVersion.c_str()); + printf("%s - Inizio Sessione - versione file: %s",logName.c_str(), logVersion.c_str()); + writeModuleInfo(); + } + + // se siamo in LM_thread devo scrivere il thread nel nome del file + std::hash hasher; + auto dwThreadID = hasher(std::this_thread::get_id()); + if (LogMode == LM_Thread || LogMode == LM_Module_Thread) { + std::stringstream th; + th << std::setiosflags(std::ios::hex | std::ios::uppercase); + th << std::setw(8); + th << dwThreadID << ".log"; + + logPath.replace(threadPos, threadPos + 14, th.str()); + } + FILE *lf = nullptr; +#ifdef WIN32 + fopen_s(&lf,logPath.c_str(), "a+t"); +#else + //lf = fopen(logPath.c_str(), "a+t"); + lf = 0; +#endif + if (lf) { + + struct stat lstat_buf; + struct stat fstat_buf; + + int r = lstat(logPath.c_str(), &lstat_buf); + + /* handle the case of the lstat failing first */ + if (r == -1) { + fclose(lf); + return; + } + + if (S_ISLNK(lstat_buf.st_mode)) { + fclose(lf); + return; + } + + /* Get the properties of the opened file descriptor */ + r = stat(logPath.c_str(), &fstat_buf); + if (r == -1) { + fclose(lf); + return; + } + + if (lstat_buf.st_dev != fstat_buf.st_dev + || lstat_buf.st_ino != fstat_buf.st_ino + || (S_IFMT & lstat_buf.st_mode) != (S_IFMT & fstat_buf.st_mode)) { + fclose(lf); + return; + } + + vfprintf(lf, format, params); + fprintf(lf, "\n"); + fclose(lf); + } + +// printf(format, params); +// printf("\n", NULL); + } +#ifdef _DEBUG +#ifdef WIN32 + int dtLen = (int)strnlen(pbtDate, sizeof(pbtDate)); + vsprintf_s(pbtDate+dtLen,2048-dtLen, format, params); + dtLen = (int)strnlen(pbtDate, sizeof(pbtDate)); + sprintf_s(pbtDate + dtLen, 2048 - dtLen, "\n"); + OutputDebugString(pbtDate); +#else + puts(pbtDate); +#endif +#endif + va_end(params); +} + +void CLog::writeBinData(BYTE *data, size_t datalen) { + if (!Enabled || !Initialized || !mainEnable) return; + if (!firstGlobal && LogMode==LM_Single) { + firstGlobal =true; + write("Inizio Sessione - versione: %s",logGlobalVersion); + writeModuleInfo(); + } + if (!FirstLog && (LogMode==LM_Module || LogMode==LM_Module_Thread)) { + FirstLog=true; + write("%s - Inizio Sessione - versione file: %s",logName.c_str(), logVersion.c_str()); + writeModuleInfo(); + } + +// char pbtDate[0x800]={NULL}; + + // se siamo in LM_thread devo scrivere il thread nel nome del file + std::hash hasher; + auto dwThreadID = hasher(std::this_thread::get_id()); + if (LogMode == LM_Thread || LogMode == LM_Module_Thread) { + std::stringstream th; + th << std::setiosflags(std::ios::hex | std::ios::uppercase); + th << std::setw(8); + th << dwThreadID << ".log"; + + logPath.replace(threadPos, threadPos + 14, th.str()); + } + + FILE *lf = nullptr; +#ifdef WIN32 + fopen_s(&lf,logPath.c_str(), "a+t"); +#else + lf = fopen(logPath.c_str(), "a+t"); +#endif + if (lf) { + + struct stat lstat_buf; + struct stat fstat_buf; + + int r = lstat(logPath.c_str(), &lstat_buf); + + /* handle the case of the lstat failing first */ + if (r == -1) { + fclose(lf); + return; + } + + if (S_ISLNK(lstat_buf.st_mode)) { + fclose(lf); + return; + } + + /* Get the properties of the opened file descriptor */ + r = stat(logPath.c_str(), &fstat_buf); + if (r == -1) { + fclose(lf); + return; + } + + if (lstat_buf.st_dev != fstat_buf.st_dev + || lstat_buf.st_ino != fstat_buf.st_ino + || (S_IFMT & lstat_buf.st_mode) != (S_IFMT & fstat_buf.st_mode)) { + fclose(lf); + return; + } + + + if (datalen>100) datalen=100; + for (size_t i=0; i -#include -//#include -#include -#include - -extern CLog Log; - -DWORD ERR_ATTRIBUTE_IS_SENSITIVE = 0x40000008; -DWORD ERR_OBJECT_HASNT_ATTRIBUTE = 0x40000009; - -BYTE hex2byte(char h) { - if (h>='0' && h<='9') return(h-'0'); - if (h>='A' && h<='F') return(h+10-'A'); - if (h>='a' && h<='f') return(h+10-'a'); - return(0); -} - -bool ishexdigit(char c) { - if (c>='0' && c<='9') return true; - if (c>='a' && c<='f') return true; - if (c>='A' && c<='F') return true; - return false; -} - -unsigned long countHexData(const std::string &data) { - unsigned long cnt = 0; - unsigned long slen= data.size(); - for (unsigned long i=0; i dt; - - - unsigned long slen=data.size(); - for (unsigned long i=0; i0) - ba = ByteArray(&dt[0], dt.size()); - else - ba.clear(); -} - -std::string HexByte(uint8_t data, bool uppercase) { - std::stringstream dmp; - dmp << std::hex << std::setfill('0'); - if (uppercase) - dmp << std::uppercase; - dmp << std::setw(2) << static_cast(data); - return dmp.str(); -} - -std::string dumpHexData(ByteArray data, std::string& dump) { - dumpHexData(data,dump,true,true); - return dump; -} - -std::string dumpHexData(ByteArray data, std::string& dump, bool withSpace, bool uppercase) { - std::stringstream dmp; - dmp << std::hex << std::setfill('0'); - if (uppercase) - dmp << std::uppercase; - for (unsigned long i = 0; i(data[i]); - if (withSpace) - dmp << " "; - } - dump.assign(dmp.str()); - return dump; -} - -std::string dumpHexData(ByteArray data) { - std::string str; - return dumpHexData(data, str, true, true); -} - -void Debug(ByteArray ba) { - std::string out; - dumpHexData(ba,out); - OutputDebugString("%s", out.c_str()); - OutputDebugString("%s", "\n"); -} - -std::string dumpHexDataLowerCase(ByteArray data, std::string& dump) { - return dumpHexData(data, dump, false, false); -} - -void PutPaddingBT0(ByteArray& ba, long dwLen) { - init_func - - if (dwLen>ba.size()) - throw logged_error("Lunghezza del padding errata"); - - ba.left(ba.size()-dwLen).fill(0); - exit_func -} - - -void PutPaddingBT1(ByteArray &ba, unsigned long dwLen) { - init_func - if (dwLen>ba.size()-3) - throw logged_error("Lunghezza del padding errata"); - - ba[0]=0; - ba[1]=1; - ba.mid(2,ba.size()-dwLen-3).fill(0xff); - ba[ba.size()-dwLen-1]=0; - exit_func -} - -void PutPaddingBT2(ByteArray &ba, unsigned long dwLen) { - init_func - if (dwLen>ba.size()-3) - throw logged_error("Lunghezza del padding errata"); - - ba[0]=0; - ba[1]=2; - ba.mid(2, ba.size() - dwLen - 3).random(); - ba[ba.size() - dwLen - 1] = 0; - exit_func -} - -unsigned long RemoveSha1(ByteArray &paddedData) { - static uint8_t SHA1Algo[] = { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 }; - if (paddedData.left(sizeof(SHA1Algo)) == VarToByteArray(SHA1Algo)) - return sizeof(SHA1Algo); - throw logged_error("OID Algoritmo SHA1 non presente"); -} - -unsigned long RemoveSha256(ByteArray &paddedData) { - static uint8_t SHA256Algo[] = { 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 }; - if (paddedData.left(sizeof(SHA256Algo)) == VarToByteArray(SHA256Algo)) - return sizeof(SHA256Algo); - throw logged_error("OID Algoritmo SHA256 non presente"); -} - -unsigned long RemovePaddingBT1(ByteArray &paddedData) { - init_func - if (paddedData[0]!=0) - throw logged_error("Errore nel padding"); - if (paddedData[1]!=1) - throw logged_error("Errore nel padding"); - for (unsigned long i = 2; i= 0; i--) { - if (paddedData[i]!=0) { - if (paddedData[i]!=0x80) { - throw logged_error("Errore nel padding"); - } else { - return i; - } - } - } - throw logged_error("Errore nel padding"); - exit_func -} - -unsigned long ANSIPadLen(unsigned long Len) { - if ((Len & 0x7) == 0) - return(Len); - else - return(Len - (Len & 0x7) + 0x08); -} - -void ANSIPad(ByteArray &Data, unsigned long DataLen) { - init_func - Data.mid(DataLen).fill(0); - exit_func - -} - -unsigned long ISOPadLen16(unsigned long Len) { - if ((Len & 0x10f) == 0) - return(Len + 16); - else - return(Len - (Len & 0x0f) + 0x10); -} - -unsigned long ISOPadLen(unsigned long Len) { - if ((Len & 0x7) == 0) - return(Len+8); - else - return(Len - (Len & 0x7) + 0x08); -} - -void ISOPad(const ByteArray& Data, unsigned long DataLen) { - init_func -// printf("\nisopad 0: %s\n", dumpHexData(Data).c_str()); - - Data.mid(DataLen).fill(0); - Data[DataLen]=0x80; - -// printf("isopad 1: %s\n", dumpHexData(Data).c_str()); - - exit_func -} - -ByteDynArray ISOPad16(const ByteArray &data) { - init_func - ByteDynArray resp(ISOPadLen16(data.size())); - resp.copy(data); - ISOPad(resp, data.size()); - return resp; - exit_func -} - -ByteDynArray ISOPad(const ByteArray& data) { - init_func - ByteDynArray resp(ISOPadLen(data.size())); - resp.copy(data); - ISOPad(resp,data.size()); - - //printf("resp: %s\n", dumpHexData(resp).c_str()); // DEBUG - - return resp; - exit_func -} - -long ByteArrayToInt(ByteArray &ba) { - init_func - long val=0; - for (unsigned long i = 0; i>=8; - } - return tLen; -} -void putASN1Tag(unsigned int tag, ByteArray &data) { - int tPos=0; - while (tag!=0) { - uint8_t b = tag >> 24; - if (b!=0) { - data[tPos]=b; - tPos++; - } - tag<<=8; - } -} - -unsigned long ASN1LLength(unsigned long len) { - if (len<0x80) - return 1; - else { - // vediamo quanti byte mi servono... - if (len<=0xff) - return 2; - else if (len<=0xffff) - return 3; - else if (len<=0xffffff) - return 4; - else if (len<=0xffffffff) - return 5; - } - throw logged_error("Lunghezza ASN1 non valida"); -} - -void putASN1Length(unsigned long len, ByteArray &data) { - if (len < 0x80) { - data[0] = (uint8_t)len; - } else { - if (len <= 0xff) { - data[0] = (0x81); - data[1] = (uint8_t)(len); - } else if (len <= 0xffff) { - data[0] = (0x82); - data[1] = (uint8_t)(len >> 8); - data[2] = (len & 0xff); - } else if (len <= 0xffffff) { - data[0] = (0x83); - data[1] = (uint8_t)(len >> 16); - data[2] = ((len >> 8) & 0xff); - data[3] = (len & 0xff); - } else if (len <= 0xffffffff) { - data[0] = (0x84); - data[1] = (uint8_t)(len >> 24); - data[2] = ((len >> 16) & 0xff); - data[3] = ((len >> 8) & 0xff); - data[4] = (len & 0xff); - } - } -} - -std::string stdPrintf(const char *format, ...) { - va_list args; - va_start(args, format); - - auto size = std::snprintf(nullptr, 0, format, args); - std::string result(size + 1, '\0'); - std::sprintf(&result[0], format, args); - - va_end(args); - return result; -} - -SYSTEMTIME convertStringToSystemTime(const char *dateTimeString) { - SYSTEMTIME systime; - - memset(&systime,0,sizeof(systime)); - // Date string should be "yyyyMMddhhmm" - sscanf(dateTimeString, "%04hi%02hi%02hiT%02hi%02hi%02hiZ", - &systime.wYear, - &systime.wMonth, - &systime.wDay, - &systime.wHour, - &systime.wMinute, - &systime.wSecond - ); - return systime; -} + +#include "util.h" +//#include +#include +//#include +#include +#include +#include "../LOGGER/Logger.h" + +extern CLog Log; +using namespace CieIDLogger; + +DWORD ERR_ATTRIBUTE_IS_SENSITIVE = 0x40000008; +DWORD ERR_OBJECT_HASNT_ATTRIBUTE = 0x40000009; + +BYTE hex2byte(char h) { + if (h>='0' && h<='9') return(h-'0'); + if (h>='A' && h<='F') return(h+10-'A'); + if (h>='a' && h<='f') return(h+10-'a'); + return(0); +} + +bool ishexdigit(char c) { + if (c>='0' && c<='9') return true; + if (c>='a' && c<='f') return true; + if (c>='A' && c<='F') return true; + return false; +} + +unsigned long countHexData(const std::string &data) { + unsigned long cnt = 0; + unsigned long slen= data.size(); + for (unsigned long i=0; i dt; + + + unsigned long slen=data.size(); + for (unsigned long i=0; i0) + ba = ByteArray(&dt[0], dt.size()); + else + ba.clear(); +} + +std::string HexByte(uint8_t data, bool uppercase) { + std::stringstream dmp; + dmp << std::hex << std::setfill('0'); + if (uppercase) + dmp << std::uppercase; + dmp << std::setw(2) << static_cast(data); + return dmp.str(); +} + +std::string dumpHexData(ByteArray data, std::string& dump) { + dumpHexData(data,dump,true,true); + return dump; +} + +std::string dumpHexData(ByteArray data, std::string& dump, bool withSpace, bool uppercase) { + std::stringstream dmp; + dmp << std::hex << std::setfill('0'); + if (uppercase) + dmp << std::uppercase; + for (unsigned long i = 0; i(data[i]); + if (withSpace) + dmp << " "; + } + dump.assign(dmp.str()); + return dump; +} + +std::string dumpHexData(ByteArray data) { + std::string str; + return dumpHexData(data, str, true, true); +} + +void Debug(ByteArray ba) { + std::string out; + dumpHexData(ba,out); + LOG_DEBUG(out.c_str()); +} + +std::string dumpHexDataLowerCase(ByteArray data, std::string& dump) { + return dumpHexData(data, dump, false, false); +} + +void PutPaddingBT0(ByteArray& ba, long dwLen) { + init_func + + if (dwLen>ba.size()) + throw logged_error("Lunghezza del padding errata"); + + ba.left(ba.size()-dwLen).fill(0); + exit_func +} + + +void PutPaddingBT1(ByteArray &ba, unsigned long dwLen) { + init_func + if (dwLen>ba.size()-3) + throw logged_error("Lunghezza del padding errata"); + + ba[0]=0; + ba[1]=1; + ba.mid(2,ba.size()-dwLen-3).fill(0xff); + ba[ba.size()-dwLen-1]=0; + exit_func +} + +void PutPaddingBT2(ByteArray &ba, unsigned long dwLen) { + init_func + if (dwLen>ba.size()-3) + throw logged_error("Lunghezza del padding errata"); + + ba[0]=0; + ba[1]=2; + ba.mid(2, ba.size() - dwLen - 3).random(); + ba[ba.size() - dwLen - 1] = 0; + exit_func +} + +unsigned long RemoveSha1(ByteArray &paddedData) { + static uint8_t SHA1Algo[] = { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 }; + if (paddedData.left(sizeof(SHA1Algo)) == VarToByteArray(SHA1Algo)) + return sizeof(SHA1Algo); + throw logged_error("OID Algoritmo SHA1 non presente"); +} + +unsigned long RemoveSha256(ByteArray &paddedData) { + static uint8_t SHA256Algo[] = { 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 }; + if (paddedData.left(sizeof(SHA256Algo)) == VarToByteArray(SHA256Algo)) + return sizeof(SHA256Algo); + throw logged_error("OID Algoritmo SHA256 non presente"); +} + +unsigned long RemovePaddingBT1(ByteArray &paddedData) { + init_func + if (paddedData[0]!=0) + throw logged_error("Errore nel padding"); + if (paddedData[1]!=1) + throw logged_error("Errore nel padding"); + for (unsigned long i = 2; i= 0; i--) { + if (paddedData[i]!=0) { + if (paddedData[i]!=0x80) { + throw logged_error("Errore nel padding"); + } else { + return i; + } + } + } + throw logged_error("Errore nel padding"); + exit_func +} + +unsigned long ANSIPadLen(unsigned long Len) { + if ((Len & 0x7) == 0) + return(Len); + else + return(Len - (Len & 0x7) + 0x08); +} + +void ANSIPad(ByteArray &Data, unsigned long DataLen) { + init_func + Data.mid(DataLen).fill(0); + exit_func + +} + +unsigned long ISOPadLen16(unsigned long Len) { + if ((Len & 0x10f) == 0) + return(Len + 16); + else + return(Len - (Len & 0x0f) + 0x10); +} + +unsigned long ISOPadLen(unsigned long Len) { + if ((Len & 0x7) == 0) + return(Len+8); + else + return(Len - (Len & 0x7) + 0x08); +} + +void ISOPad(const ByteArray& Data, unsigned long DataLen) { + init_func +// printf("\nisopad 0: %s\n", dumpHexData(Data).c_str()); + + Data.mid(DataLen).fill(0); + Data[DataLen]=0x80; + +// printf("isopad 1: %s\n", dumpHexData(Data).c_str()); + + exit_func +} + +ByteDynArray ISOPad16(const ByteArray &data) { + init_func + ByteDynArray resp(ISOPadLen16(data.size())); + resp.copy(data); + ISOPad(resp, data.size()); + return resp; + exit_func +} + +ByteDynArray ISOPad(const ByteArray& data) { + init_func + ByteDynArray resp(ISOPadLen(data.size())); + resp.copy(data); + ISOPad(resp,data.size()); + + //printf("resp: %s\n", dumpHexData(resp).c_str()); // DEBUG + + return resp; + exit_func +} + +long ByteArrayToInt(ByteArray &ba) { + init_func + long val=0; + for (unsigned long i = 0; i>=8; + } + return tLen; +} +void putASN1Tag(unsigned int tag, ByteArray &data) { + int tPos=0; + while (tag!=0) { + uint8_t b = tag >> 24; + if (b!=0) { + data[tPos]=b; + tPos++; + } + tag<<=8; + } +} + +unsigned long ASN1LLength(unsigned long len) { + if (len<0x80) + return 1; + else { + // vediamo quanti byte mi servono... + if (len<=0xff) + return 2; + else if (len<=0xffff) + return 3; + else if (len<=0xffffff) + return 4; + else if (len<=0xffffffff) + return 5; + } + throw logged_error("Lunghezza ASN1 non valida"); +} + +void putASN1Length(unsigned long len, ByteArray &data) { + if (len < 0x80) { + data[0] = (uint8_t)len; + } else { + if (len <= 0xff) { + data[0] = (0x81); + data[1] = (uint8_t)(len); + } else if (len <= 0xffff) { + data[0] = (0x82); + data[1] = (uint8_t)(len >> 8); + data[2] = (len & 0xff); + } else if (len <= 0xffffff) { + data[0] = (0x83); + data[1] = (uint8_t)(len >> 16); + data[2] = ((len >> 8) & 0xff); + data[3] = (len & 0xff); + } else if (len <= 0xffffffff) { + data[0] = (0x84); + data[1] = (uint8_t)(len >> 24); + data[2] = ((len >> 16) & 0xff); + data[3] = ((len >> 8) & 0xff); + data[4] = (len & 0xff); + } + } +} + +std::string stdPrintf(const char *format, ...) { + va_list args; + va_start(args, format); + + auto size = std::snprintf(nullptr, 0, format, args); + std::string result(size + 1, '\0'); + std::sprintf(&result[0], format, args); + + va_end(args); + return result; +} + +SYSTEMTIME convertStringToSystemTime(const char *dateTimeString) { + SYSTEMTIME systime; + + memset(&systime,0,sizeof(systime)); + // Date string should be "yyyyMMddhhmm" + sscanf(dateTimeString, "%04hi%02hi%02hiT%02hi%02hi%02hiZ", + &systime.wYear, + &systime.wMonth, + &systime.wDay, + &systime.wHour, + &systime.wMinute, + &systime.wSecond + ); + return systime; +} diff --git a/libcie-pkcs11/meson.build b/libcie-pkcs11/meson.build index f86f6046..769a7280 100644 --- a/libcie-pkcs11/meson.build +++ b/libcie-pkcs11/meson.build @@ -1,6 +1,6 @@ project('libcie-pkcs11', 'cpp', - version : '1.4.1', + version : '1.4.2', license : 'MIT') add_project_arguments('-fPIC', language : 'cpp') @@ -16,6 +16,7 @@ inc = include_directories('/usr/include/PCSC', '.', 'Crypto', 'CSP', + 'LOGGER', 'PCSC', 'PKCS11', 'UI', @@ -40,6 +41,7 @@ cie_pkcs11_sources = ['Util/UUCByteArray.cpp', 'CSP/PINManager.cpp', 'CSP/AbilitaCIE.cpp', 'CSP/IAS.cpp', + 'LOGGER/Logger.cpp', 'PCSC/Token.cpp', 'PCSC/PCSC.cpp', 'PCSC/APDU.cpp', @@ -75,7 +77,7 @@ libcie_pkcs11 = library( pkg_mod = import('pkgconfig') pkg_mod.generate( libraries : libcie_pkcs11, - version : '1.4.1', + version : '1.4.2', name : 'libcie-pkcs11', filebase : 'cie-pkcs11', description : 'A library to enable CIE authentication.' diff --git a/packages/cie-middleware/PKGBUILD b/packages/cie-middleware/PKGBUILD index b5598665..8cb2119c 100644 --- a/packages/cie-middleware/PKGBUILD +++ b/packages/cie-middleware/PKGBUILD @@ -5,10 +5,10 @@ targets=( "ubuntu" ) pkgname="cie-middleware" -pkgver="1.4.1" +pkgver="1.4.2" pkgrel="1" -pkgdesc="Middleware della CIE (Carta di Identità Elettronica) per Linux" -pkgdesclong=("Middleware della CIE (Carta di Identità Elettronica) per Linux") +pkgdesc="A fork of Middleware della CIE (Carta di Identità Elettronica) per Linux" +pkgdesclong=("A fork of Middleware della CIE (Carta di Identità Elettronica) per Linux") maintainer="boiano.gianluca@gmail.com" url="https://github.com/italia/cie-middleware-linux" arch="amd64" @@ -97,8 +97,7 @@ build:archlinux() { export JAVA_HOME=/usr/lib/jvm/default/ cd "${srcdir}/${pkgname}-linux-main" gradle -b cie-java/build.gradle standalone - cd libcie-pkcs11 - meson builddir + meson builddir libcie-pkcs11 meson configure -Dprefix=/usr builddir meson compile -C builddir } @@ -107,8 +106,7 @@ build:fedora() { export JAVA_HOME=/usr/lib/jvm/java-11-openjdk/ cd "${srcdir}/${pkgname}-linux-main" ../gradle-7.3/bin/gradle -b cie-java/build.gradle standalone - cd libcie-pkcs11 - meson builddir + meson builddir libcie-pkcs11 meson configure -Dprefix=/usr builddir meson compile -C builddir } @@ -117,8 +115,7 @@ build:opensuse() { export JAVA_HOME=/usr/lib64/jvm/java-11-openjdk/ cd "${srcdir}/${pkgname}-linux-main" ../gradle-7.3/bin/gradle -b cie-java/build.gradle standalone - cd libcie-pkcs11 - meson builddir + meson builddir libcie-pkcs11 meson configure -Dprefix=/usr builddir meson compile -C builddir } @@ -128,8 +125,7 @@ build:ubuntu() { pip3 install ninja meson cd "${srcdir}/${pkgname}-linux-main" ../gradle-7.3/bin/gradle -b cie-java/build.gradle standalone - cd libcie-pkcs11 - meson builddir + meson builddir libcie-pkcs11 meson configure -Dprefix=/usr builddir meson compile -C builddir } @@ -150,6 +146,5 @@ package() { "${pkgdir}/usr/share/licenses/cieid/LICENSE" # Lib - cd libcie-pkcs11 - DESTDIR="${pkgdir}" meson install -C builddir + DESTDIR="${pkgdir}" meson install -C builddir }