Compare commits
330 Commits
0.21.0-rc1
...
golem/tess
Author | SHA1 | Date |
---|---|---|
giomba | 932bd27549 | |
giomba | b965e20bfd | |
giomba | 060d8ddb19 | |
giomba | 5167b30043 | |
giomba | 606edadb13 | |
Jakub Jelen | c902e19921 | |
Vesa Jääskeläinen | e97fec4d91 | |
Vesa Jääskeläinen | cababca4d5 | |
Vesa Jääskeläinen | 63a5a493a6 | |
Vesa Jääskeläinen | 1b344a4847 | |
Vesa Jääskeläinen | 7007eda0ba | |
Vesa Jääskeläinen | 1991fa24ae | |
Vesa Jääskeläinen | 6431f69dcc | |
Frank Morgner | 7d315b5546 | |
Doug Engert | 4c923c637c | |
Jakub Jelen | b67261ab27 | |
Jakub Jelen | 68b7efb591 | |
Jakub Jelen | 3048156db0 | |
Jakub Jelen | 1e43a6a1af | |
Doug Engert | c6a9b5699a | |
Doug Engert | 445a6324de | |
Doug Engert | 456ac56693 | |
Jakub Jelen | 8453c0d99a | |
Jakub Jelen | d47f42b12a | |
Jakub Jelen | 01cf556ba2 | |
Jakub Jelen | f43d3f8042 | |
Jakub Jelen | 5d338739ac | |
Jakub Jelen | e683c531f6 | |
Jakub Jelen | 1b329093f7 | |
Jakub Jelen | bc9b9df869 | |
Frank Morgner | 99656deaf4 | |
Jakub Jelen | 9a5a008093 | |
Jakub Jelen | d34e84c78d | |
Frank Morgner | d90048e5bb | |
Jakub Jelen | aa6574b60e | |
Jakub Jelen | fd6b64b91b | |
Alessio Di Mauro | 2f94a6b155 | |
Doug Engert | aebebac432 | |
Frank Morgner | c42792c216 | |
Stephan Mühlstrasser | 151583ce26 | |
Jakub Jelen | 9be6dc6606 | |
Jakub Jelen | 9d1a214340 | |
Jakub Jelen | fc2fecc80e | |
Jakub Jelen | ffd6e2a576 | |
Jaime Hablutzel | 465375bda2 | |
Jakub Jelen | 33426df3ff | |
Jakub Jelen | 8e4134841d | |
Jakub Jelen | a8a4bddfad | |
Jakub Jelen | a69ab7c70c | |
Jakub Jelen | fd96d2c960 | |
Jakub Jelen | 1b92501ef9 | |
Jakub Jelen | 07f5e63abf | |
Jakub Jelen | 12be677cb8 | |
Jakub Jelen | e4cf0e7b39 | |
Jakub Jelen | 0b45e78e4f | |
Yaroslav Isakov | fc08818f6f | |
Yaroslav Isakov | 23dc52c903 | |
Yaroslav Isakov | 29410c170e | |
Yaroslav Isakov | f356d301b9 | |
Doug Engert | 48a11c0634 | |
Doug Engert | f1bc07dec1 | |
Doug Engert | 8dfafe4fc2 | |
Vincent JARDIN | 5256bc3d3d | |
Vincent JARDIN | 180737d1b6 | |
Vincent JARDIN | f0c059ede8 | |
Vincent JARDIN | 46c50dc51d | |
Georgi Kirichkov | ca01d2c5e2 | |
Georgi Kirichkov | 5ae0ef4f41 | |
Georgi Kirichkov | 072c64aaed | |
Alon Bar-Lev | 35a8a1d7e1 | |
Ludovic Rousseau | 2ea5ed8ddd | |
Jakub Jelen | 2f145f5804 | |
Jakub Jelen | 613b56ee55 | |
Jakub Jelen | d0b847c6cf | |
Jakub Jelen | 835cee2e5a | |
Jakub Jelen | 06ac408bb4 | |
divinehawk | 98663528cf | |
ihsinme | 50eaa6bf57 | |
Frank Morgner | 32004e74ce | |
Anton Logachev | 570fc56c47 | |
Doug Engert | 19611682bd | |
Vincent JARDIN | a21bcf4b41 | |
Vincent JARDIN | e93bd3983c | |
Frank Morgner | 3f19991556 | |
Frank Morgner | 4ecb4b39ac | |
Frank Morgner | 75f24d2af7 | |
Frank Morgner | 2063a1d334 | |
Vincent JARDIN | e3a3722ad1 | |
Vincent JARDIN | fcd2e665fe | |
Vincent JARDIN | 405ecfc402 | |
Vincent JARDIN | 544aa4cc6b | |
Vincent JARDIN | 137286858f | |
Vincent JARDIN | 39b4472f38 | |
Vincent JARDIN | 396cbc46cf | |
Frank Morgner | 4912f05701 | |
Peter Marschall | 344ac0abe6 | |
Jakub Jelen | d6ec00c870 | |
Peter Popovec | dd48facd38 | |
Peter Popovec | 7d274a0d72 | |
Jakub Jelen | ef17b3fb89 | |
Jakub Jelen | cae5c71f90 | |
Jakub Jelen | 4b3c6dec07 | |
Frank Morgner | 991bb8a141 | |
Frank Morgner | a83069b89f | |
Carsten Blüggel | edb7ed25e4 | |
Frank Morgner | 545e47b29e | |
Vincent JARDIN | 1a3666364d | |
Vincent JARDIN | 0df0f80b55 | |
Philip Prindeville | b9c0addf88 | |
yehj | c3c5f2d518 | |
Frank Morgner | 83162c5c87 | |
Frank Morgner | ce0d409205 | |
Jakub Jelen | 7114fb71b5 | |
Jakub Jelen | 9cc942fd47 | |
Jakub Jelen | 7d0abdc192 | |
Jakub Jelen | 370eda4bd8 | |
Frank Morgner | 5f9085fedb | |
Marco Trevisan (Treviño) | 845eac4250 | |
Vincent JARDIN | 40e9a9c830 | |
Vincent JARDIN | b18234a7d9 | |
Jakub Jelen | 5d4daf6c92 | |
Jakub Jelen | 715c17c469 | |
Jakub Jelen | d5dea2dd1b | |
Jakub Jelen | 16b7c60fd3 | |
Frank Morgner | 05648b0604 | |
Vincent JARDIN | fc0df4e5d5 | |
Vincent JARDIN | 76507508d7 | |
Vincent JARDIN | 4119b2c3e7 | |
Vincent JARDIN | b508349010 | |
Vincent JARDIN | 20f359ea04 | |
Vincent JARDIN | c581d1b26f | |
Vincent JARDIN | fd83e885f7 | |
Vincent JARDIN | 6efd7b3029 | |
Vincent JARDIN | 41edcaa413 | |
Vincent JARDIN | 7cd713d15d | |
Vincent JARDIN | fd97f49a84 | |
Vincent JARDIN | 560692221b | |
Vincent JARDIN | acb8822444 | |
Jakub Jelen | 40c50a3a42 | |
Frank Morgner | 4512676795 | |
Frank Morgner | 26fac9592d | |
Raul Metsma | b9080c16d6 | |
Frank Morgner | aae9254018 | |
Raul Metsma | 578128e464 | |
Frank Morgner | 1325d5c333 | |
Raul Metsma | 85c5610d39 | |
Frank Morgner | 63e6683384 | |
Peter Popovec | f46b617397 | |
Frank Morgner | 8e614bfe6e | |
Jakub Jelen | 8d61d0d20d | |
Jakub Jelen | 1ef79e99f7 | |
Jakub Jelen | 60632100a0 | |
Jakub Jelen | 63031b2193 | |
Jakub Jelen | 544dcc6827 | |
Jakub Jelen | 2fa6700599 | |
Jakub Jelen | 45e262f537 | |
Jakub Jelen | b5f26051bb | |
Jakub Jelen | b8266a4c86 | |
Jakub Jelen | 0ce245a411 | |
Jakub Jelen | 56af7de137 | |
Jakub Jelen | c39e31b274 | |
Jakub Jelen | ae771a135f | |
Jakub Jelen | cb8c7647ca | |
Jakub Jelen | a020b85d94 | |
Jakub Jelen | 73e283b4b1 | |
Jakub Jelen | 64b61a7556 | |
Jakub Jelen | 9bd139d1e4 | |
Jakub Jelen | 8c4d325576 | |
Doug Engert | 0380142482 | |
Jakub Jelen | 091b7670eb | |
Jakub Jelen | 35cfc291ce | |
Jakub Jelen | 485b6cff44 | |
Jakub Jelen | 32ec1f92b9 | |
Jakub Jelen | e7d390f9dd | |
Jakub Jelen | a965829f52 | |
Jakub Jelen | 5d5c391793 | |
Jakub Jelen | 5178e74e1b | |
Jakub Jelen | 2fb688683e | |
Jakub Jelen | b351bf5ea4 | |
Jakub Jelen | caae75758c | |
Jakub Jelen | 80f80317d1 | |
Jakub Jelen | 095c28e372 | |
Jakub Jelen | 0455a5665e | |
Jakub Jelen | c78fa164c9 | |
Jakub Jelen | a30bf95eed | |
Jakub Jelen | a5a6757d10 | |
Jakub Jelen | e82f875047 | |
Jakub Jelen | 86e01d7c47 | |
Jakub Jelen | f726d4f201 | |
Frank Morgner | 5b42a62ec0 | |
Frank Morgner | fe6864c5f3 | |
Frank Morgner | c2670b0787 | |
Frank Morgner | 881dca94ef | |
Frank Morgner | d353a46d04 | |
Peter Popovec | 6738d456ac | |
Frank Morgner | 999874fb1c | |
Luka Logar | c80375eb4c | |
Frank Morgner | a322c95d35 | |
Jakub Jelen | 5f7c91e54f | |
Jakub Jelen | 46cfe89b3c | |
Jakub Jelen | a567ab9dca | |
Jakub Jelen | cee431a3ce | |
Jakub Jelen | ffed34663d | |
Jakub Jelen | 3b556ef618 | |
Jakub Jelen | 1dbe4b5a5b | |
Jakub Jelen | 2f232f217b | |
Jakub Jelen | ae1cf0be90 | |
Jakub Jelen | 1252aca9f1 | |
Jakub Jelen | 17d8980cde | |
Jakub Jelen | 9c91a4327e | |
Jakub Jelen | 7ba89daae6 | |
Jakub Jelen | 251c4f6b76 | |
alt3r 3go | 3044557299 | |
ihsinme | 6372adeb20 | |
ihsinme | 0a3d7a28a7 | |
Zhang Xiaohui | 49788678fe | |
Zhang Xiaohui | 1c4a01d766 | |
Vincent JARDIN | 66e5600b27 | |
Jakub Jelen | 8a6026abf5 | |
Jakub Jelen | da247384e7 | |
Jakub Jelen | 176b20f339 | |
Jakub Jelen | cb074c5fa0 | |
Jakub Jelen | 5633129bd8 | |
Jakub Jelen | 0d693f63cb | |
Doug Engert | b5ddaf6e02 | |
Doug Engert | f704e4f23e | |
Doug Engert | 1b4e9f1d4a | |
Doug Engert | d369965a7f | |
Jakub Jelen | e1c8361ff3 | |
Jakub Jelen | 44d429c3ad | |
Jakub Jelen | edaf921eb6 | |
Jakub Jelen | ac81764308 | |
Jakub Jelen | a6ed34bbb5 | |
Peter Popovec | 26adaf519c | |
Peter Popovec | a3ca7613cd | |
Doug Engert | 0b0deae4be | |
Doug Engert | 521d420c42 | |
Doug Engert | 285db1ef29 | |
Peter Popovec | 6049cb926c | |
Jakub Jelen | 5f16ffae84 | |
Jakub Jelen | 03cbf91be5 | |
Jakub Jelen | b820bdf5b3 | |
Jakub Jelen | 1db88374bb | |
Peter Popovec | ba85ae75e3 | |
Peter Popovec | ce7fa42958 | |
Frank Morgner | 7a090b994e | |
Jakub Jelen | 219c6cc494 | |
Jakub Jelen | 96ae693d5a | |
Jakub Jelen | db18a72c64 | |
Jakub Jelen | 7f9e8ba85c | |
Jakub Jelen | d224b2612d | |
Jakub Jelen | 03079a9413 | |
Jakub Jelen | 6e25924eb0 | |
Jakub Jelen | 224e265266 | |
Jakub Jelen | 8e71118cd4 | |
Jakub Jelen | 7f0166ab12 | |
Jakub Jelen | 95122abe2e | |
Jakub Jelen | 47151e9335 | |
Jakub Jelen | e58e7e1428 | |
Jakub Jelen | 23eb606d86 | |
Jakub Jelen | c7c689c74d | |
Jakub Jelen | 910020aeec | |
Jakub Jelen | 9cda87e200 | |
Jakub Jelen | d25009cde6 | |
Jakub Jelen | 3135fccdca | |
Jakub Jelen | 049b2a8754 | |
Jakub Jelen | 66f274dcaf | |
Jakub Jelen | b48696539d | |
Jakub Jelen | 88543529a2 | |
Jakub Jelen | f7b0ce3dac | |
Doug Engert | f443c391b0 | |
Carsten Blüggel | f8af905574 | |
Jakub Jelen | 1ae8b60425 | |
Jakub Jelen | 5df913b7f5 | |
Jakub Jelen | 69544553c3 | |
Jakub Jelen | 196bf9e574 | |
Peter Popovec | a089353e1f | |
Jakub Jelen | f015746d22 | |
Jakub Jelen | 78cdab949f | |
Jakub Jelen | 3ffe24cfb6 | |
Jakub Jelen | fb83cd0439 | |
Jakub Jelen | 61eb4e487e | |
Frank Morgner | 175c357c37 | |
Jakub Jelen | 85e08ae675 | |
rickyepoderi | 3ce249f365 | |
Frank Morgner | 98beb86a38 | |
Frank Morgner | 480da424a5 | |
Jakub Jelen | 0365c3ce6c | |
Jakub Jelen | 3d257410b2 | |
Jakub Jelen | 63bb85b050 | |
Jakub Jelen | 871e4f2ac6 | |
Jakub Jelen | 55a5556949 | |
Jakub Jelen | af2fb6938c | |
Jakub Jelen | 8a6708c163 | |
Jakub Jelen | d0e5d62bf5 | |
Jakub Jelen | 3eae6a031c | |
Jakub Jelen | 00ad8644e6 | |
Doug Engert | 483e153182 | |
Frank Morgner | 30180986a0 | |
Frank Morgner | e13294b085 | |
Frank Morgner | 0e55a3497c | |
Frank Morgner | 96a9fcd628 | |
Jakub Jelen | 412372b024 | |
Jakub Jelen | 65461e4eb5 | |
Jakub Jelen | 445c651549 | |
Jakub Jelen | c8b2e82713 | |
Jakub Jelen | 5eccebb4ee | |
Jakub Jelen | b5b1afe401 | |
Jakub Jelen | d3451faa21 | |
Frank Morgner | 4554d69119 | |
Frank Morgner | c4a75eb1c2 | |
Frank Morgner | 3bad4089fd | |
Frank Morgner | b145c2c30e | |
Frank Morgner | e05574d942 | |
Frank Morgner | 4d6ed77a4a | |
Zhang Xiaohui | c5508c5eae | |
Zhang Xiaohui | e8f27abd02 | |
Arya Senna | 4cc0d0c7c9 | |
Arya Senna | 64de4a5001 | |
Carsten Blüggel | 8098b7de61 | |
Frank Morgner | c621f39034 | |
Jakub Jelen | 704afd0e2d | |
Jakub Jelen | 42254ae792 | |
Jakub Jelen | 88f3d19479 | |
Doug Engert | ce28ea8162 | |
w00475903 | 26a404d6a5 | |
Zhang Xiaohui | 0dc3dcbc00 | |
w00475903 | 7551e14c58 | |
Frank Morgner | d0c44b9ddc | |
Frank Morgner | fca2ba9474 |
|
@ -0,0 +1,3 @@
|
|||
BasedOnStyle: Google
|
||||
IndentWidth: 4
|
||||
|
|
@ -18,9 +18,18 @@ security set-keychain-settings -t 3600 -u $KEY_CHAIN
|
|||
|
||||
# Add certificates to keychain and allow codesign to access them
|
||||
curl -L https://developer.apple.com/certificationauthority/AppleWWDRCA.cer > AppleWWDRCA.cer
|
||||
security import AppleWWDRCA.cer -k ~/Library/Keychains/$KEY_CHAIN -T /usr/bin/codesign
|
||||
security import certificate.cer -k ~/Library/Keychains/$KEY_CHAIN -T /usr/bin/codesign
|
||||
security import certificate.p12 -k ~/Library/Keychains/$KEY_CHAIN -P $KEY_PASSWORD -T /usr/bin/codesign
|
||||
security import AppleWWDRCA.cer \
|
||||
-k ~/Library/Keychains/$KEY_CHAIN \
|
||||
-T /usr/bin/codesign -T /usr/bin/productsign
|
||||
security import DeveloperIDApplication.cer \
|
||||
-k ~/Library/Keychains/$KEY_CHAIN \
|
||||
-T /usr/bin/codesign -T /usr/bin/productsign
|
||||
security import DeveloperIDInstaller.cer \
|
||||
-k ~/Library/Keychains/$KEY_CHAIN \
|
||||
-T /usr/bin/codesign -T /usr/bin/productsign
|
||||
security import key.p12 \
|
||||
-k ~/Library/Keychains/$KEY_CHAIN -P $KEY_PASSWORD \
|
||||
-T /usr/bin/codesign -T /usr/bin/productsign
|
||||
security unlock-keychain -p travis $KEY_CHAIN
|
||||
|
||||
# https://docs.travis-ci.com/user/common-build-problems/#mac-macos-sierra-1012-code-signing-errors
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig;
|
||||
|
||||
if [ "$GITHUB_EVENT_NAME" == "pull_request" ]; then
|
||||
PR_NUMBER=$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }')
|
||||
if [ "$GITHUB_BASE_REF" == "master" ]; then
|
||||
./bootstrap.ci -s "-pr$PR_NUMBER"
|
||||
else
|
||||
./bootstrap.ci -s "$GITHUB_BASE_REF-pr$PR_NUMBER"
|
||||
fi
|
||||
else
|
||||
BRANCH=$(echo $GITHUB_REF | awk 'BEGIN { FS = "/" } ; { print $3 }')
|
||||
if [ "$BRANCH" == "master" ]; then
|
||||
./bootstrap
|
||||
else
|
||||
./bootstrap.ci -s "$BRANCH"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$RUNNER_OS" == "macOS" ]; then
|
||||
./MacOSX/build
|
||||
exit $?
|
||||
fi
|
||||
|
||||
if [ "$1" == "mingw" -o "$1" == "mingw32" ]; then
|
||||
if [ "$1" == "mingw" ]; then
|
||||
HOST=x86_64-w64-mingw32
|
||||
elif [ "$1" == "mingw32" ]; then
|
||||
HOST=i686-w64-mingw32
|
||||
fi
|
||||
unset CC
|
||||
unset CXX
|
||||
./configure --host=$HOST --with-completiondir=/tmp --disable-openssl --disable-readline --disable-zlib --disable-notify --prefix=$PWD/win32/opensc || cat config.log;
|
||||
make -j 2
|
||||
# no point in running tests on mingw
|
||||
else
|
||||
# normal procedure
|
||||
./configure --disable-dependency-tracking
|
||||
make -j 2
|
||||
make check
|
||||
fi
|
||||
|
||||
# this is broken in old ubuntu
|
||||
if [ "$1" == "dist" ]; then
|
||||
make distcheck
|
||||
make dist
|
||||
fi
|
||||
|
||||
sudo make install
|
||||
if [ "$1" == "mingw" -o "$1" == "mingw32" ]; then
|
||||
# pack installed files
|
||||
wine "C:/Program Files/Inno Setup 5/ISCC.exe" win32/OpenSC.iss
|
||||
fi
|
|
@ -6,15 +6,22 @@ BUILDPATH=${PWD}
|
|||
BRANCH="`git log --max-count=1 --date=short --abbrev=8 --pretty=format:"%cd_%h"`"
|
||||
|
||||
git clone --single-branch https://${GH_TOKEN}@github.com/OpenSC/Nightly.git > /dev/null 2>&1
|
||||
cd Nightly
|
||||
pushd Nightly
|
||||
git checkout -b "${BRANCH}"
|
||||
|
||||
for file in ${BUILDPATH}/win32/Output/OpenSC*.exe ${BUILDPATH}/opensc*.tar.gz ${BUILDPATH}/OpenSC*.dmg ${BUILDPATH}/OpenSC*.msi ${BUILDPATH}/OpenSC*.zip
|
||||
do
|
||||
if [ -f ${file} ]
|
||||
then
|
||||
cp ${file} .
|
||||
git add `basename ${file}`
|
||||
# github only allows a maximum file size of 50MB
|
||||
MAX_MB_FILESIZE=50
|
||||
if [ $(du -m "$file" | cut -f 1) -ge $MAX_MB_FILESIZE ]
|
||||
then
|
||||
split -b ${MAX_MB_FILESIZE}m ${file} `basename ${file}`.
|
||||
else
|
||||
cp ${file} .
|
||||
fi
|
||||
git add `basename ${file}`*
|
||||
fi
|
||||
done
|
||||
|
||||
|
@ -23,6 +30,7 @@ i=0
|
|||
while [ $i -le 10 ] && ! git push --quiet --set-upstream origin "${BRANCH}"
|
||||
do
|
||||
sleep $[ ( $RANDOM % 32 ) + 1 ]s
|
||||
git pull --rebase origin "${BRANCH}"
|
||||
git pull --rebase origin --strategy-option ours "${BRANCH}"
|
||||
i=$(( $i + 1 ))
|
||||
done
|
||||
popd
|
||||
|
|
|
@ -4,5 +4,5 @@ set -ex -o xtrace
|
|||
|
||||
pushd .github/
|
||||
security delete-keychain mac-build.keychain
|
||||
rm -f certificate.cer certificate.p12
|
||||
rm -f DeveloperIDApplication.cer DeveloperIDInstaller.cer key.p12
|
||||
popd
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,24 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
# Select the right java
|
||||
sudo update-java-alternatives -s java-1.8.0-openjdk-amd64
|
||||
sudo update-alternatives --get-selections | grep ^java
|
||||
export PATH="/usr/lib/jvm/java-8-openjdk-amd64/bin/:$PATH"
|
||||
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/
|
||||
env | grep -i openjdk
|
||||
|
||||
# VSmartcard
|
||||
./.github/setup-vsmartcard.sh
|
||||
|
||||
# Javacard SDKs
|
||||
git clone https://github.com/martinpaljak/oracle_javacard_sdks.git
|
||||
export JC_HOME=$PWD/oracle_javacard_sdks/jc222_kit
|
||||
export JC_CLASSIC_HOME=$PWD/oracle_javacard_sdks/jc305u3_kit
|
||||
|
||||
# jCardSim
|
||||
git clone https://github.com/arekinath/jcardsim.git
|
||||
pushd jcardsim
|
||||
env | grep -i openjdk
|
||||
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/
|
||||
mvn initialize && mvn clean install
|
||||
popd
|
|
@ -0,0 +1,42 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
DEPS="docbook-xsl libpcsclite-dev xsltproc gengetopt libcmocka-dev help2man pcscd check softhsm2 pcsc-tools libtool make autoconf autoconf-archive automake libssl-dev zlib1g-dev pkg-config libreadline-dev openssl git"
|
||||
|
||||
if [ "$1" == "clang-tidy" ]; then
|
||||
DEPS="$DEPS clang-tidy"
|
||||
elif [ "$1" == "cac" ]; then
|
||||
DEPS="$DEPS libglib2.0-dev libnss3-dev gnutls-bin libusb-dev libudev-dev flex libnss3-tools"
|
||||
elif [ "$1" == "oseid" ]; then
|
||||
DEPS="$DEPS socat gawk xxd"
|
||||
elif [ "$1" == "piv" -o "$1" == "isoapplet" -o "$1" == "gidsapplet" -o "$1" == "openpgp" ]; then
|
||||
if [ "$1" == "piv" ]; then
|
||||
DEPS="$DEPS cmake"
|
||||
fi
|
||||
DEPS="$DEPS ant openjdk-8-jdk"
|
||||
elif [ "$1" == "mingw" -o "$1" == "mingw32" ]; then
|
||||
DEPS="$DEPS wine wine32 xvfb wget"
|
||||
sudo dpkg --add-architecture i386
|
||||
if [ "$1" == "mingw" ]; then
|
||||
DEPS="$DEPS binutils-mingw-w64-x86-64 gcc-mingw-w64-x86-64 mingw-w64"
|
||||
elif [ "$1" == "mingw32" ]; then
|
||||
DEPS="$DEPS binutils-mingw-w64-i686 gcc-mingw-w64-i686"
|
||||
fi
|
||||
fi
|
||||
|
||||
# make sure we do not get prompts
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y build-essential $DEPS
|
||||
|
||||
if [ "$1" == "mingw" -o "$1" == "mingw32" ]; then
|
||||
if [ ! -f "$(winepath 'C:/Program Files/Inno Setup 5/ISCC.exe')" ]; then
|
||||
/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac -screen 0 1280x1024x16
|
||||
export DISPLAY=:99.0
|
||||
[ -d isetup ] || mkdir isetup
|
||||
pushd isetup
|
||||
[ -f isetup-5.5.6.exe ] || wget http://files.jrsoftware.org/is/5/isetup-5.5.6.exe
|
||||
sleep 5 # make sure the X server is ready ?
|
||||
wine isetup-5.5.6.exe /SILENT /VERYSILENT /SP- /SUPPRESSMSGBOXES /NORESTART
|
||||
popd
|
||||
fi
|
||||
fi
|
|
@ -0,0 +1,32 @@
|
|||
#!/bin/bash
|
||||
|
||||
brew install automake
|
||||
|
||||
# gengetopt
|
||||
curl https://ftp.gnu.org/gnu/gengetopt/gengetopt-2.23.tar.xz -L --output gengetopt-2.23.tar.xz
|
||||
tar xfj gengetopt-2.23.tar.xz
|
||||
pushd gengetopt-2.23
|
||||
./configure && make
|
||||
sudo make install
|
||||
popd
|
||||
|
||||
# help2man
|
||||
curl https://ftp.gnu.org/gnu/help2man/help2man-1.47.16.tar.xz -L --output help2man-1.47.16.tar.xz
|
||||
tar xjf help2man-1.47.16.tar.xz
|
||||
pushd help2man-1.47.16
|
||||
./configure && make
|
||||
sudo make install
|
||||
popd
|
||||
|
||||
# openSCToken
|
||||
export PATH="/usr/local/opt/ccache/libexec:$PATH"
|
||||
git clone https://github.com/frankmorgner/OpenSCToken.git
|
||||
sudo rm -rf /Library/Developer/CommandLineTools;
|
||||
|
||||
# TODO make the encrypted key working in github
|
||||
if [ "$GITHUB_EVENT_NAME" == "pull_request" -a -n "$encrypted_3b9f0b9d36d1_key" ]; then
|
||||
openssl aes-256-cbc -K $encrypted_3b9f0b9d36d1_key -iv $encrypted_3b9f0b9d36d1_iv -in .github/secrets.tar.enc -out .github/secrets.tar -d;
|
||||
.github/add_signing_key.sh;
|
||||
else
|
||||
unset CODE_SIGN_IDENTITY INSTALLER_SIGN_IDENTITY;
|
||||
fi
|
|
@ -0,0 +1,8 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ ! -d "vsmartcard" ]; then
|
||||
git clone https://github.com/frankmorgner/vsmartcard.git
|
||||
fi
|
||||
pushd vsmartcard/virtualsmartcard
|
||||
autoreconf -vis && ./configure && make -j2 && sudo make install
|
||||
popd
|
|
@ -0,0 +1,47 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
# install the opensc
|
||||
sudo make install
|
||||
export LD_LIBRARY_PATH=/usr/local/lib
|
||||
|
||||
# VSmartcard
|
||||
./.github/setup-vsmartcard.sh
|
||||
|
||||
# libcacard
|
||||
if [ ! -d "libcacard" ]; then
|
||||
git clone https://gitlab.freedesktop.org/spice/libcacard.git
|
||||
fi
|
||||
pushd libcacard
|
||||
./autogen.sh --prefix=/usr && make -j2 && sudo make install
|
||||
popd
|
||||
|
||||
# virt_cacard
|
||||
if [ ! -d "virt_cacard" ]; then
|
||||
git clone https://github.com/Jakuje/virt_cacard.git
|
||||
fi
|
||||
pushd virt_cacard
|
||||
./autogen.sh && ./configure && make
|
||||
popd
|
||||
|
||||
sudo /etc/init.d/pcscd restart
|
||||
|
||||
pushd src/tests/p11test/
|
||||
./p11test -s 0 -p 12345678 -i -o virt_cacard.json &
|
||||
sleep 5
|
||||
popd
|
||||
|
||||
# virt_cacard startup
|
||||
pushd virt_cacard
|
||||
./setup-softhsm2.sh
|
||||
export SOFTHSM2_CONF=$PWD/softhsm2.conf
|
||||
./virt_cacard &
|
||||
wait $(ps aux | grep '[p]11test'| awk '{print $2}')
|
||||
kill -9 $(ps aux | grep '[v]irt_cacard'| awk '{print $2}')
|
||||
popd
|
||||
|
||||
# cleanup -- this would break later uses of pcscd
|
||||
pushd vsmartcard/virtualsmartcard
|
||||
sudo make uninstall
|
||||
popd
|
||||
|
||||
diff -u3 src/tests/p11test/virt_cacard{_ref,}.json
|
|
@ -0,0 +1,36 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
# install the opensc
|
||||
sudo make install
|
||||
export LD_LIBRARY_PATH=/usr/local/lib
|
||||
|
||||
# setup java stuff
|
||||
. .github/setup-java.sh
|
||||
|
||||
# GidsApplet
|
||||
git clone https://github.com/vletoux/GidsApplet.git;
|
||||
javac -classpath jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar GidsApplet/src/com/mysmartlogon/gidsApplet/*.java;
|
||||
echo "com.licel.jcardsim.card.applet.0.AID=A000000397425446590201" > gids_jcardsim.cfg;
|
||||
echo "com.licel.jcardsim.card.applet.0.Class=com.mysmartlogon.gidsApplet.GidsApplet" >> gids_jcardsim.cfg;
|
||||
echo "com.licel.jcardsim.card.ATR=3B80800101" >> gids_jcardsim.cfg;
|
||||
echo "com.licel.jcardsim.vsmartcard.host=localhost" >> gids_jcardsim.cfg;
|
||||
echo "com.licel.jcardsim.vsmartcard.port=35963" >> gids_jcardsim.cfg;
|
||||
|
||||
# log errors from pcscd to console
|
||||
sudo systemctl stop pcscd.service pcscd.socket
|
||||
sudo /usr/sbin/pcscd -f &
|
||||
PCSCD_PID=$!
|
||||
|
||||
|
||||
# start the applet and run couple of commands against that
|
||||
java -noverify -cp GidsApplet/src/:jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar com.licel.jcardsim.remote.VSmartCard gids_jcardsim.cfg >/dev/null &
|
||||
PID=$!;
|
||||
sleep 5;
|
||||
opensc-tool --card-driver default --send-apdu 80b80000190bA0000003974254465902010bA00000039742544659020100;
|
||||
opensc-tool -n;
|
||||
gids-tool --initialize --pin 123456 --admin-key 000000000000000000000000000000000000000000000000 --serial 00000000000000000000000000000000;
|
||||
kill -9 $PID
|
||||
|
||||
|
||||
# cleanup
|
||||
sudo kill -9 $PCSCD_PID
|
|
@ -0,0 +1,41 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
# install the opensc
|
||||
sudo make install
|
||||
export LD_LIBRARY_PATH=/usr/local/lib
|
||||
|
||||
# setup java stuff
|
||||
./.github/setup-java.sh
|
||||
|
||||
# The ISO applet
|
||||
git clone https://github.com/philipWendland/IsoApplet.git;
|
||||
javac -classpath jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar IsoApplet/src/net/pwendland/javacard/pki/isoapplet/*.java;
|
||||
echo "com.licel.jcardsim.card.applet.0.AID=F276A288BCFBA69D34F31001" > isoapplet_jcardsim.cfg;
|
||||
echo "com.licel.jcardsim.card.applet.0.Class=net.pwendland.javacard.pki.isoapplet.IsoApplet" >> isoapplet_jcardsim.cfg;
|
||||
echo "com.licel.jcardsim.card.ATR=3B80800101" >> isoapplet_jcardsim.cfg;
|
||||
echo "com.licel.jcardsim.vsmartcard.host=localhost" >> isoapplet_jcardsim.cfg;
|
||||
echo "com.licel.jcardsim.vsmartcard.port=35963" >> isoapplet_jcardsim.cfg;
|
||||
|
||||
# log errors from pcscd to console
|
||||
sudo systemctl stop pcscd.service pcscd.socket
|
||||
sudo /usr/sbin/pcscd -f &
|
||||
PCSCD_PID=$!
|
||||
|
||||
# start the applet and run couple of commands against that
|
||||
java -noverify -cp IsoApplet/src/:jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar com.licel.jcardsim.remote.VSmartCard isoapplet_jcardsim.cfg >/dev/null &
|
||||
PID=$!;
|
||||
sleep 5;
|
||||
opensc-tool --card-driver default --send-apdu 80b800001a0cf276a288bcfba69d34f310010cf276a288bcfba69d34f3100100;
|
||||
opensc-tool -n;
|
||||
pkcs15-init --create-pkcs15 --so-pin 123456 --so-puk 0123456789abcdef;
|
||||
pkcs15-tool --change-pin --pin 123456 --new-pin 654321;
|
||||
pkcs15-tool --unblock-pin --puk 0123456789abcdef --new-pin 123456;
|
||||
pkcs15-init --generate-key rsa/2048 --id 1 --key-usage decrypt,sign --auth-id FF --pin 123456;
|
||||
pkcs15-init --generate-key rsa/2048 --id 2 --key-usage decrypt --auth-id FF --pin 123456;
|
||||
pkcs15-init --generate-key ec/secp256r1 --id 3 --key-usage sign --auth-id FF --pin 123456;
|
||||
pkcs15-tool -D;
|
||||
pkcs11-tool -l -t -p 123456;
|
||||
kill -9 $PID;
|
||||
|
||||
# cleanup
|
||||
sudo kill -9 $PCSCD_PID
|
|
@ -0,0 +1,40 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
# install the opensc
|
||||
sudo make install
|
||||
export LD_LIBRARY_PATH=/usr/local/lib
|
||||
|
||||
# setup java stuff
|
||||
. .github/setup-java.sh
|
||||
|
||||
# The OpenPGP applet
|
||||
git clone --recursive https://github.com/Yubico/ykneo-openpgp.git;
|
||||
cd ykneo-openpgp;
|
||||
ant -DJAVACARD_HOME=${JC_HOME};
|
||||
cd $TRAVIS_BUILD_DIR;
|
||||
echo "com.licel.jcardsim.card.applet.0.AID=D2760001240102000000000000010000" > openpgp_jcardsim.cfg;
|
||||
echo "com.licel.jcardsim.card.applet.0.Class=openpgpcard.OpenPGPApplet" >> openpgp_jcardsim.cfg;
|
||||
echo "com.licel.jcardsim.card.ATR=3B80800101" >> openpgp_jcardsim.cfg;
|
||||
echo "com.licel.jcardsim.vsmartcard.host=localhost" >> openpgp_jcardsim.cfg;
|
||||
echo "com.licel.jcardsim.vsmartcard.port=35963" >> openpgp_jcardsim.cfg;
|
||||
|
||||
# log errors from pcscd to console
|
||||
sudo systemctl stop pcscd.service pcscd.socket
|
||||
sudo /usr/sbin/pcscd -f &
|
||||
PCSCD_PID=$!
|
||||
|
||||
|
||||
# start the applet and run couple of commands against that
|
||||
java -noverify -cp ykneo-openpgp/applet/bin:jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar com.licel.jcardsim.remote.VSmartCard openpgp_jcardsim.cfg >/dev/null &
|
||||
PID=$!;
|
||||
sleep 5;
|
||||
opensc-tool --card-driver default --send-apdu 80b800002210D276000124010200000000000001000010D276000124010200000000000001000000;
|
||||
opensc-tool -n;
|
||||
openpgp-tool --verify CHV3 --pin 12345678 --gen-key 2;
|
||||
pkcs15-init --verify --auth-id 3 --pin 12345678 --delete-objects privkey,pubkey --id 2 --generate-key rsa/2048;
|
||||
pkcs11-tool -l -t -p 123456;
|
||||
kill -9 $PID
|
||||
|
||||
|
||||
# cleanup
|
||||
sudo kill -9 $PCSCD_PID
|
|
@ -0,0 +1,54 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
# install the opensc
|
||||
sudo make install
|
||||
export LD_LIBRARY_PATH=/usr/local/lib
|
||||
|
||||
if [ ! -d oseid ]; then
|
||||
git clone https://github.com/popovec/oseid
|
||||
fi
|
||||
pushd oseid/src/
|
||||
make -f Makefile.console
|
||||
if [ ! -d tmp ]; then
|
||||
mkdir tmp
|
||||
fi
|
||||
socat -d -d pty,link=tmp/OsEIDsim.socket,raw,echo=0 "exec:build/console/console ...,pty,raw,echo=0" &
|
||||
PID=$!
|
||||
sleep 1
|
||||
echo "# OsEIDsim" > tmp/reader.conf
|
||||
echo 'FRIENDLYNAME "OsEIDsim"' >> tmp/reader.conf
|
||||
echo "DEVICENAME $PWD/tmp/OsEIDsim.socket" >> tmp/reader.conf
|
||||
echo "LIBPATH $PWD/build/console/libOsEIDsim.so.0.0.1" >> tmp/reader.conf
|
||||
echo "CHANNELID 1" >> tmp/reader.conf
|
||||
sudo mv tmp/reader.conf /etc/reader.conf.d/reader.conf
|
||||
cat /etc/reader.conf.d/reader.conf
|
||||
popd
|
||||
|
||||
sudo /etc/init.d/pcscd restart
|
||||
|
||||
# Needed for tput to not report warnings
|
||||
export TERM=xterm-256color
|
||||
|
||||
pushd oseid/tools
|
||||
echo | ./OsEID-tool INIT
|
||||
./OsEID-tool RSA-CREATE-KEYS
|
||||
./OsEID-tool RSA-UPLOAD-KEYS
|
||||
./OsEID-tool RSA-DECRYPT-TEST
|
||||
./OsEID-tool RSA-SIGN-PKCS11-TEST
|
||||
./OsEID-tool EC-CREATE-KEYS
|
||||
./OsEID-tool EC-UPLOAD-KEYS
|
||||
./OsEID-tool EC-SIGN-TEST
|
||||
./OsEID-tool EC-SIGN-PKCS11-TEST
|
||||
./OsEID-tool EC-ECDH-TEST
|
||||
popd
|
||||
|
||||
# this does not work as we have random key IDs in here
|
||||
#pushd src/tests/p11test/
|
||||
#./p11test -s 0 -p 11111111 -o oseid.json || true
|
||||
#diff -u3 oseid_ref.json oseid.json
|
||||
#popd
|
||||
|
||||
# cleanup -- this would break later uses of pcscd
|
||||
kill -9 $PID
|
||||
rm oseid/src/card_mem
|
||||
sudo rm /etc/reader.conf.d/reader.conf
|
|
@ -0,0 +1,45 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
# install the opensc
|
||||
sudo make install
|
||||
export LD_LIBRARY_PATH=/usr/local/lib
|
||||
|
||||
# setup java stuff
|
||||
. .github/setup-java.sh
|
||||
|
||||
# The PIV Applet
|
||||
git clone --recursive https://github.com/arekinath/PivApplet.git
|
||||
pushd PivApplet
|
||||
JC_HOME=${JC_CLASSIC_HOME} ant dist
|
||||
popd
|
||||
|
||||
# yubico-piv-tool is needed for PIV Applet management
|
||||
git clone https://github.com/Yubico/yubico-piv-tool.git
|
||||
pushd yubico-piv-tool
|
||||
mkdir build
|
||||
pushd build
|
||||
cmake .. && make && sudo make install
|
||||
popd
|
||||
popd
|
||||
|
||||
|
||||
# log errors from pcscd to console
|
||||
sudo systemctl stop pcscd.service pcscd.socket
|
||||
sudo /usr/sbin/pcscd -f &
|
||||
PCSCD_PID=$!
|
||||
|
||||
|
||||
# start the applet and run couple of commands against that
|
||||
java -noverify -cp PivApplet/bin/:jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar com.licel.jcardsim.remote.VSmartCard PivApplet/test/jcardsim.cfg >/dev/null &
|
||||
PID=$!
|
||||
sleep 5
|
||||
opensc-tool --card-driver default --send-apdu 80b80000120ba000000308000010000100050000020F0F7f
|
||||
opensc-tool -n
|
||||
yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P 123456 -s 9e -a generate -A RSA2048
|
||||
yubico-piv-tool -v 9999 -r 'Virtual PCD 00 00' -P 123456 -s 9a -a generate -A ECCP256
|
||||
pkcs11-tool -l -t -p 123456
|
||||
kill -9 $PID
|
||||
|
||||
|
||||
# cleanup
|
||||
sudo kill -9 $PCSCD_PID
|
|
@ -0,0 +1,28 @@
|
|||
name: CIFuzz
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- '**.c'
|
||||
- '**.h'
|
||||
jobs:
|
||||
Fuzzing:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Build Fuzzers
|
||||
id: build
|
||||
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
|
||||
with:
|
||||
oss-fuzz-project-name: 'opensc'
|
||||
dry-run: false
|
||||
- name: Run Fuzzers
|
||||
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
|
||||
with:
|
||||
oss-fuzz-project-name: 'opensc'
|
||||
fuzz-seconds: 600
|
||||
dry-run: false
|
||||
- name: Upload Crash
|
||||
uses: actions/upload-artifact@v1
|
||||
if: failure() && steps.build.outcome == 'success'
|
||||
with:
|
||||
name: artifacts
|
||||
path: ./out/artifacts
|
|
@ -0,0 +1,176 @@
|
|||
name: Linux
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- '**.c'
|
||||
- '**.h'
|
||||
push:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: .github/setup-linux.sh
|
||||
- run: .github/build.sh dist
|
||||
- uses: actions/cache@v2
|
||||
id: cache-build
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ runner.os }}-${{ github.sha }}
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: opensc-build
|
||||
path:
|
||||
opensc*.tar.gz
|
||||
|
||||
build-ubuntu-18:
|
||||
runs-on: ubuntu-18.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: .github/setup-linux.sh
|
||||
- run: .github/build.sh
|
||||
- uses: actions/cache@v2
|
||||
id: cache-build
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ runner.os }}-18-${{ github.sha }}
|
||||
|
||||
build-mingw:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: .github/setup-linux.sh mingw
|
||||
- run: .github/build.sh mingw
|
||||
- name: Cache build artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: opensc-build-mingw
|
||||
path:
|
||||
win32/Output/OpenSC*.exe
|
||||
|
||||
build-mingw32:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: .github/setup-linux.sh mingw32
|
||||
- run: .github/build.sh mingw32
|
||||
- name: Cache build artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: opensc-build-mingw32
|
||||
path:
|
||||
win32/Output/OpenSC*.exe
|
||||
|
||||
test-piv:
|
||||
runs-on: ubuntu-18.04
|
||||
needs: [build-ubuntu-18]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/cache@v2
|
||||
id: cache-build
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ runner.os }}-18-${{ github.sha }}
|
||||
- run: .github/setup-linux.sh piv
|
||||
- run: .github/test-piv.sh
|
||||
|
||||
test-isoapplet:
|
||||
runs-on: ubuntu-18.04
|
||||
needs: [build-ubuntu-18]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/cache@v2
|
||||
id: cache-build
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ runner.os }}-18-${{ github.sha }}
|
||||
- run: .github/setup-linux.sh isoapplet
|
||||
- run: .github/test-isoapplet.sh
|
||||
|
||||
test-gidsapplet:
|
||||
runs-on: ubuntu-18.04
|
||||
needs: [build-ubuntu-18]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/cache@v2
|
||||
id: cache-build
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ runner.os }}-18-${{ github.sha }}
|
||||
- run: .github/setup-linux.sh gidsapplet
|
||||
- run: .github/test-gidsapplet.sh
|
||||
|
||||
test-openpgp:
|
||||
runs-on: ubuntu-18.04
|
||||
needs: [build-ubuntu-18]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/cache@v2
|
||||
id: cache-build
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ runner.os }}-18-${{ github.sha }}
|
||||
- run: .github/setup-linux.sh openpgp
|
||||
# the openpgp sometimes fails
|
||||
- run: .github/test-openpgp.sh || true
|
||||
|
||||
build-clang-tidy:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/cache@v2
|
||||
id: cache-build
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ runner.os }}-${{ github.sha }}
|
||||
- run: .github/setup-linux.sh clang-tidy
|
||||
- run: .github/build.sh
|
||||
|
||||
test-cac:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/cache@v2
|
||||
id: cache-build
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ runner.os }}-${{ github.sha }}
|
||||
- run: .github/setup-linux.sh cac
|
||||
- run: .github/test-cac.sh
|
||||
|
||||
test-oseid:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/cache@v2
|
||||
id: cache-build
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ runner.os }}-${{ github.sha }}
|
||||
- run: .github/setup-linux.sh oseid
|
||||
- run: .github/test-oseid.sh
|
||||
|
||||
push-artifacts:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build, build-mingw]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/cache@v2
|
||||
id: cache-build
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ runner.os }}-${{ github.sha }}
|
||||
- name: Pull mingw build artifacts
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: opensc-build-mingw
|
||||
- run: git config --global user.email "builds@github.com"
|
||||
- run: git config --global user.name "Github Actions";
|
||||
- run: .github/push_artifacts.sh "Github Actions ${GITHUB_REF}"
|
||||
if: ${{ github.event_name != 'pull_request' && github.repository == 'OpenSC/OpenSC' }}
|
|
@ -0,0 +1,39 @@
|
|||
name: OSX
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- '**.c'
|
||||
- '**.h'
|
||||
push:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: .github/setup-macos.sh
|
||||
- run: .github/build.sh
|
||||
- name: Cache build artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: opensc-build-macos
|
||||
path:
|
||||
OpenSC*.dmg
|
||||
|
||||
push-artifacts:
|
||||
runs-on: macos-latest
|
||||
needs: [build]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Pull build artifacts
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: opensc-build-macos
|
||||
- run: git config --global user.email "builds@github.com"
|
||||
- run: git config --global user.name "Github Actions";
|
||||
- run: .github/push_artifacts.sh "Github Actions ${GITHUB_REF}"
|
||||
if: ${{ github.event_name != 'pull_request' && github.repository == 'OpenSC/OpenSC' }}
|
||||
# TODO this fails probably because the key is not loaded in keychain before with
|
||||
# security: SecKeychainDelete: The specified keychain could not be found.
|
||||
# - run: .github/remove_signing_key.sh; rm -f .github/secrets.tar
|
|
@ -64,6 +64,7 @@ ChangeLog
|
|||
doc/tools/*-tool
|
||||
doc/tools/eidenv
|
||||
doc/tools/opensc-explorer
|
||||
doc/tools/pkcs11-register
|
||||
doc/tools/pkcs15-crypt
|
||||
doc/tools/pkcs15-init
|
||||
doc/tools/opensc-asn1
|
||||
|
@ -79,6 +80,7 @@ src/tools/pkcs15-init
|
|||
src/tools/eidenv
|
||||
src/tools/opensc-explorer
|
||||
src/tools/cardos-info
|
||||
src/tools/gcns
|
||||
src/tools/sceac-example
|
||||
src/tools/opensc-notify
|
||||
src/tools/opensc-notify.plist
|
||||
|
@ -120,5 +122,7 @@ tests/*.trs
|
|||
src/tests/unittests/*.log
|
||||
src/tests/unittests/*.trs
|
||||
src/tests/unittests/asn1
|
||||
src/tests/unittests/compression
|
||||
src/tests/unittests/simpletlv
|
||||
|
||||
version.m4.ci
|
||||
|
|
95
.travis.yml
95
.travis.yml
|
@ -6,9 +6,13 @@ matrix:
|
|||
os: osx
|
||||
osx_image: xcode9.4
|
||||
env: DO_PUSH_ARTIFACT=yes
|
||||
- compiler: clang
|
||||
os: osx
|
||||
osx_image: xcode12.2
|
||||
env: DO_PUSH_ARTIFACT=yes
|
||||
- compiler: clang
|
||||
os: linux
|
||||
dist: bionic
|
||||
dist: focal
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
dist: bionic
|
||||
|
@ -17,7 +21,7 @@ matrix:
|
|||
- ENABLE_DOC=--enable-doc
|
||||
- compiler: gcc
|
||||
os: linux
|
||||
dist: bionic
|
||||
dist: focal
|
||||
env:
|
||||
- DO_SIMULATION=oseid
|
||||
- env:
|
||||
|
@ -47,40 +51,55 @@ env:
|
|||
- COVERITY_SCAN_PROJECT_NAME="$TRAVIS_REPO_SLUG"
|
||||
- SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)
|
||||
|
||||
addons:
|
||||
apt_packages:
|
||||
- binutils-mingw-w64-i686
|
||||
- binutils-mingw-w64-x86-64
|
||||
- docbook-xsl
|
||||
- gcc-mingw-w64-i686
|
||||
- gcc-mingw-w64-x86-64
|
||||
- libpcsclite-dev
|
||||
- mingw-w64
|
||||
- xsltproc
|
||||
- gengetopt
|
||||
- libcmocka-dev
|
||||
- help2man
|
||||
- pcscd
|
||||
- pcsc-tools
|
||||
- check
|
||||
- ant
|
||||
- socat
|
||||
- cmake
|
||||
# Commented out because of a bug in travis images for Focal:
|
||||
# https://travis-ci.community/t/clang-10-was-recently-broken-on-linux-unmet-dependencies-for-clang-10-clang-tidy-10-valgrind/11527
|
||||
#addons:
|
||||
# apt_packages:
|
||||
# - binutils-mingw-w64-i686
|
||||
# - binutils-mingw-w64-x86-64
|
||||
# - docbook-xsl
|
||||
# - gcc-mingw-w64-i686
|
||||
# - gcc-mingw-w64-x86-64
|
||||
# - libpcsclite-dev
|
||||
# - mingw-w64
|
||||
# - xsltproc
|
||||
# - gengetopt
|
||||
# - libcmocka-dev
|
||||
# - help2man
|
||||
# - pcscd
|
||||
# - pcsc-tools
|
||||
# - check
|
||||
# - ant
|
||||
# - socat
|
||||
# - cmake
|
||||
# - clang-tidy
|
||||
# - softhsm2
|
||||
|
||||
before_install:
|
||||
# brew install gengetopt help2man cmocka ccache llvm;
|
||||
# export PATH="/usr/local/opt/ccache/libexec:/usr/local/opt/llvm/bin:$PATH";
|
||||
# add magic notarization flags for macOS, see https://github.com/akeru-inc/xcnotary/blob/master/README.md
|
||||
# homebrew is dead slow in older images due to the many updates it would need to download and build.
|
||||
# here, we build the additional dependencies manually to get around this
|
||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
brew update;
|
||||
brew uninstall libtool;
|
||||
brew install libtool;
|
||||
brew install gengetopt help2man cmocka ccache;
|
||||
curl https://ftp.gnu.org/gnu/gengetopt/gengetopt-2.23.tar.xz -L --output gengetopt-2.23.tar.xz;
|
||||
tar xfj gengetopt-2.23.tar.xz;
|
||||
pushd gengetopt-2.23;
|
||||
./configure && make;
|
||||
sudo make install;
|
||||
popd;
|
||||
curl https://ftp.gnu.org/gnu/help2man/help2man-1.47.16.tar.xz -L --output help2man-1.47.16.tar.xz;
|
||||
tar xjf help2man-1.47.16.tar.xz;
|
||||
pushd help2man-1.47.16;
|
||||
./configure && make;
|
||||
sudo make install;
|
||||
popd;
|
||||
export PATH="/usr/local/opt/ccache/libexec:$PATH";
|
||||
git clone https://github.com/frankmorgner/OpenSCToken.git;
|
||||
sudo rm -rf /Library/Developer/CommandLineTools;
|
||||
fi
|
||||
- if [ "$TRAVIS_OS_NAME" = "osx" -a "$TRAVIS_PULL_REQUEST" = "false" -a -n "$encrypted_3b9f0b9d36d1_key" ]; then
|
||||
openssl aes-256-cbc -K $encrypted_3b9f0b9d36d1_key -iv $encrypted_3b9f0b9d36d1_iv -in .github/secrets.tar.enc -out .github/secrets.tar -d;
|
||||
.github/add_signing_key.sh;
|
||||
export OTHER_CODE_SIGN_FLAGS=--timestamp CODE_SIGN_INJECT_BASE_ENTITLEMENTS=NO CODE_SIGN_STYLE=Manual;
|
||||
git clone https://github.com/frankmorgner/OpenSCToken.git;
|
||||
else
|
||||
unset CODE_SIGN_IDENTITY INSTALLER_SIGN_IDENTITY;
|
||||
fi
|
||||
- if [ "${DO_SIMULATION}" = "javacard" ]; then
|
||||
sudo apt-get install -y openjdk-8-jdk;
|
||||
|
@ -97,6 +116,12 @@ before_install:
|
|||
- if [ -n "${HOST}" ]; then
|
||||
sudo apt-get install -y wine;
|
||||
fi
|
||||
- if [ "$TRAVIS_DIST" == "focal" ]; then
|
||||
sudo apt-get install -yq --allow-downgrades libc6=2.31-0ubuntu9.2 libc6-dev=2.31-0ubuntu9.2;
|
||||
fi
|
||||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then
|
||||
sudo -E apt-get -yq --no-install-suggests --no-install-recommends --allow-downgrades --allow-remove-essential --allow-change-held-packages install binutils-mingw-w64-i686 binutils-mingw-w64-x86-64 docbook-xsl gcc-mingw-w64-i686 gcc-mingw-w64-x86-64 libpcsclite-dev mingw-w64 xsltproc gengetopt libcmocka-dev help2man pcscd pcsc-tools check ant socat cmake clang-tidy softhsm2;
|
||||
fi
|
||||
|
||||
before_script:
|
||||
- if [ "$TRAVIS_BRANCH" = "master" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then
|
||||
|
@ -235,7 +260,7 @@ script:
|
|||
fi;
|
||||
fi
|
||||
- if [ -z "$HOST" -a "${DO_COVERITY_SCAN}" != "yes" -a -z "$DO_SIMULATION" ]; then
|
||||
make check && make dist;
|
||||
make check && make distcheck || (cat tests/*log src/tests/unittests/*log && exit 1);
|
||||
fi
|
||||
- if [ ! -z "$HOST" -a "${DO_COVERITY_SCAN}" != "yes" ]; then
|
||||
make install;
|
||||
|
@ -308,9 +333,11 @@ script:
|
|||
./OsEID-tool RSA-CREATE-KEYS;
|
||||
./OsEID-tool RSA-UPLOAD-KEYS;
|
||||
./OsEID-tool RSA-DECRYPT-TEST;
|
||||
./OsEID-tool RSA-SIGN-PKCS11-TEST;
|
||||
./OsEID-tool EC-CREATE-KEYS;
|
||||
./OsEID-tool EC-UPLOAD-KEYS;
|
||||
./OsEID-tool EC-SIGN-TEST;
|
||||
./OsEID-tool EC-SIGN-PKCS11-TEST;
|
||||
./OsEID-tool EC-ECDH-TEST;
|
||||
kill -9 $PID;
|
||||
|
||||
|
@ -318,7 +345,7 @@ script:
|
|||
fi
|
||||
- if [ "${DO_SIMULATION}" = "cac" ]; then
|
||||
cd $TRAVIS_BUILD_DIR;
|
||||
make check && sudo make install || (cat tests/*log src/tests/unittests/*log && exit);
|
||||
make check && sudo make install || (cat tests/*log src/tests/unittests/*log && exit 1);
|
||||
export LD_LIBRARY_PATH=/usr/local/lib;
|
||||
cd src/tests/p11test/;
|
||||
./p11test -s 0 -p 12345678 -i &
|
||||
|
@ -349,15 +376,11 @@ after_script:
|
|||
rm -f .github/secrets.tar;
|
||||
fi
|
||||
|
||||
before_cache:
|
||||
- brew cleanup
|
||||
|
||||
cache:
|
||||
apt: true
|
||||
ccache: true
|
||||
directories:
|
||||
- $HOME/.m2/
|
||||
- $HOME/Library/Caches/Homebrew
|
||||
- openssl_bin
|
||||
- openpace_bin
|
||||
- isetup
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<false/>
|
||||
<key>com.apple.security.automation.apple-events</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<false/>
|
||||
<key>com.apple.security.cs.disable-library-validation</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -13,18 +13,11 @@ set -ex
|
|||
test -x ./configure || ./bootstrap
|
||||
BUILDPATH=${PWD}
|
||||
|
||||
# Locate the latest OSX SDK
|
||||
SDK_PATH=$(xcrun --sdk macosx --show-sdk-path)
|
||||
|
||||
# Set SDK path
|
||||
export CFLAGS="$CFLAGS -isysroot $SDK_PATH -arch x86_64"
|
||||
|
||||
# xcodebuild doesn't read the environment variables
|
||||
# transform them into parameters
|
||||
P1="${CODE_SIGN_IDENTITY:+CODE_SIGN_IDENTITY=${CODE_SIGN_IDENTITY}}"
|
||||
P2="${OTHER_CODE_SIGN_FLAGS:+OTHER_CODE_SIGN_FLAGS=${OTHER_CODE_SIGN_FLAGS}}"
|
||||
P3="${CODE_SIGN_INJECT_BASE_ENTITLEMENTS:+CODE_SIGN_INJECT_BASE_ENTITLEMENTS=${CODE_SIGN_INJECT_BASE_ENTITLEMENTS}}"
|
||||
P4="${CODE_SIGN_STYLE:+CODE_SIGN_STYLE=${CODE_SIGN_STYLE}}"
|
||||
xcode_ver=$(xcodebuild -version | sed -En 's/Xcode[[:space:]](.*)/\1/p')
|
||||
base_ver="12.2"
|
||||
if [ $(echo -e $base_ver"\n"$xcode_ver | sort -V | head -1) == "$base_ver" ]; then
|
||||
export BUILD_ARM="true"
|
||||
fi
|
||||
|
||||
export SED=/usr/bin/sed
|
||||
PREFIX=/Library/OpenSC
|
||||
|
@ -38,19 +31,39 @@ if ! pkg-config libcrypto --atleast-version=1.0.1; then
|
|||
git clone --depth=1 https://github.com/openssl/openssl.git -b OpenSSL_1_1_1-stable
|
||||
fi
|
||||
cd openssl
|
||||
KERNEL_BITS=64 ./config no-shared --prefix=$PREFIX
|
||||
MACHINE=x86_64 ./config no-shared --prefix=$PREFIX
|
||||
make clean
|
||||
make -j 4
|
||||
make DESTDIR=$BUILDPATH/openssl_bin install_sw
|
||||
if test -n "${BUILD_ARM}"; then
|
||||
make clean
|
||||
MACHINE=arm64 KERNEL_BITS=64 ./config no-shared --prefix=$PREFIX
|
||||
make -j 4
|
||||
make DESTDIR=$BUILDPATH/openssl_arm64 install_sw
|
||||
lipo -create $BUILDPATH/openssl_arm64/$PREFIX/lib/libcrypto.a $BUILDPATH/openssl_bin/$PREFIX/lib/libcrypto.a -output libcrypto.a
|
||||
lipo -create $BUILDPATH/openssl_arm64/$PREFIX/lib/libssl.a $BUILDPATH/openssl_bin/$PREFIX/lib/libssl.a -output libssl.a
|
||||
mv libcrypto.a $BUILDPATH/openssl_bin/$PREFIX/lib/libcrypto.a
|
||||
mv libssl.a $BUILDPATH/openssl_bin/$PREFIX/lib/libssl.a
|
||||
fi
|
||||
cd ..
|
||||
fi
|
||||
export OPENSSL_CFLAGS="`env PKG_CONFIG_PATH=$BUILDPATH/openssl_bin/$PREFIX/lib/pkgconfig PKG_CONFIG_SYSROOT_DIR=$BUILDPATH/openssl_bin pkg-config --static --cflags libcrypto`"
|
||||
export OPENSSL_LIBS="` env PKG_CONFIG_PATH=$BUILDPATH/openssl_bin/$PREFIX/lib/pkgconfig PKG_CONFIG_SYSROOT_DIR=$BUILDPATH/openssl_bin pkg-config --static --libs libcrypto`"
|
||||
fi
|
||||
|
||||
# Locate the latest OSX SDK
|
||||
SDK_PATH=$(xcrun --sdk macosx --show-sdk-path)
|
||||
export CFLAGS="$CFLAGS -isysroot $SDK_PATH"
|
||||
|
||||
if test -n "${BUILD_ARM}"; then
|
||||
export CFLAGS="$CFLAGS -arch x86_64 -arch arm64"
|
||||
export LDFLAGS="$LDFLAGS -arch x86_64 -arch arm64"
|
||||
fi
|
||||
export OBJCFLAGS=$CFLAGS
|
||||
|
||||
if ! test -e $BUILDPATH/openpace_bin/$PREFIX/lib/pkgconfig; then
|
||||
if ! test -e openpace; then
|
||||
git clone --depth=1 https://github.com/frankmorgner/openpace.git -b 1.1.0
|
||||
git clone --depth=1 https://github.com/frankmorgner/openpace.git -b 1.1.1
|
||||
fi
|
||||
cd openpace
|
||||
autoreconf -vis
|
||||
|
@ -97,13 +110,17 @@ fi
|
|||
if ! test -e NotificationProxy; then
|
||||
git clone http://github.com/frankmorgner/NotificationProxy.git
|
||||
fi
|
||||
if test -n "${CODE_SIGN_IDENTITY}"; then
|
||||
xcodebuild -target NotificationProxy -configuration Release -project NotificationProxy/NotificationProxy.xcodeproj install DSTROOT=$BUILDPATH/target/Library/OpenSC/ "$P1" "$P2" "$P3" "$P4"
|
||||
if test -n "${CODE_SIGN_IDENTITY}" -a -n "${DEVELOPMENT_TEAM}"; then
|
||||
xcodebuild -target NotificationProxy -configuration Release -project NotificationProxy/NotificationProxy.xcodeproj install DSTROOT=$BUILDPATH/target/Library/OpenSC/ \
|
||||
CODE_SIGN_IDENTITY="${CODE_SIGN_IDENTITY}" DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}" OTHER_CODE_SIGN_FLAGS="--timestamp --options=runtime" CODE_SIGN_INJECT_BASE_ENTITLEMENTS=NO CODE_SIGN_STYLE=Manual
|
||||
else
|
||||
xcodebuild -target NotificationProxy -configuration Release -project NotificationProxy/NotificationProxy.xcodeproj install DSTROOT=$BUILDPATH/target/Library/OpenSC/
|
||||
fi
|
||||
mkdir -p "$BUILDPATH/target/Applications/Utilities"
|
||||
osacompile -o "$BUILDPATH/target/Applications/Utilities/OpenSC Notify.app" "MacOSX/OpenSC_Notify.applescript"
|
||||
if test -n "${CODE_SIGN_IDENTITY}"; then
|
||||
codesign --force --sign "${CODE_SIGN_IDENTITY}" --entitlements MacOSX/OpenSC_applescripts.entitlements --deep --timestamp --options runtime "$BUILDPATH/target/Applications/Utilities/OpenSC Notify.app"
|
||||
fi
|
||||
|
||||
|
||||
# Build OpenSC.tokend when XCode version < 10
|
||||
|
@ -117,14 +134,18 @@ if (( $(xcodebuild -version | sed -En 's/Xcode[[:space:]]+([0-9]+)(\.[0-9]*)*/\1
|
|||
test -L OpenSC.tokend/build/opensc-src || ln -sf ${BUILDPATH}/src OpenSC.tokend/build/opensc-src
|
||||
|
||||
# Build and copy OpenSC.tokend
|
||||
if test -n "${CODE_SIGN_IDENTITY}"; then
|
||||
xcodebuild -target OpenSC -configuration Deployment -project OpenSC.tokend/Tokend.xcodeproj install DSTROOT=${BUILDPATH}/target_tokend "$P1" $P2 "$P3" "$P4"
|
||||
if test -n "${CODE_SIGN_IDENTITY}" -a -n "${DEVELOPMENT_TEAM}"; then
|
||||
xcodebuild -target OpenSC -configuration Deployment -project OpenSC.tokend/Tokend.xcodeproj install DSTROOT=${BUILDPATH}/target_tokend \
|
||||
CODE_SIGN_IDENTITY="${CODE_SIGN_IDENTITY}" DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}" OTHER_CODE_SIGN_FLAGS="--timestamp --options=runtime" CODE_SIGN_INJECT_BASE_ENTITLEMENTS=NO CODE_SIGN_STYLE=Manual
|
||||
else
|
||||
xcodebuild -target OpenSC -configuration Deployment -project OpenSC.tokend/Tokend.xcodeproj install DSTROOT=${BUILDPATH}/target_tokend
|
||||
fi
|
||||
|
||||
TOKEND="-tokend"
|
||||
else
|
||||
# https://github.com/OpenSC/OpenSC.tokend/issues/33
|
||||
mkdir -p ${BUILDPATH}/target_tokend
|
||||
TOKEND=""
|
||||
fi
|
||||
|
||||
#if ! test -e $BUILDPATH/target/Library/Security/tokend/OpenSC.tokend/Contents/Resources/Applications/terminal-notifier.app; then
|
||||
|
@ -146,11 +167,11 @@ cp MacOSX/opensc-uninstall ${BUILDPATH}/target/usr/local/bin
|
|||
|
||||
# Prepare startup root
|
||||
mkdir -p ${BUILDPATH}/target_startup/Library/LaunchAgents
|
||||
cp src/tools/pkcs11-register.plist ${BUILDPATH}/target_startup/Library/LaunchAgents
|
||||
cp src/tools/opensc-notify.plist ${BUILDPATH}/target_startup/Library/LaunchAgents
|
||||
cp src/tools/org.opensc-project.mac.pkcs11-register.plist ${BUILDPATH}/target_startup/Library/LaunchAgents
|
||||
cp src/tools/org.opensc-project.mac.opensc-notify.plist ${BUILDPATH}/target_startup/Library/LaunchAgents
|
||||
|
||||
# Build OpenSCToken if possible
|
||||
if test -e OpenSCToken -a -n "${CODE_SIGN_IDENTITY}"; then
|
||||
if test -e OpenSCToken -a -n "${CODE_SIGN_IDENTITY}" -a -n "${DEVELOPMENT_TEAM}"; then
|
||||
cd OpenSCToken
|
||||
# make sure OpenSCToken builds with the same dependencies as before
|
||||
if ! test -e OpenSC; then
|
||||
|
@ -172,31 +193,51 @@ if test -e OpenSCToken -a -n "${CODE_SIGN_IDENTITY}"; then
|
|||
BP=${BUILDPATH}
|
||||
. ./bootstrap
|
||||
BUILDPATH=${BP}
|
||||
xcodebuild -target OpenSCTokenApp -configuration Debug -project OpenSCTokenApp.xcodeproj install DSTROOT=${BUILDPATH}/target_token "$P1" "$P2" "$P3" "$P4"
|
||||
mkdir ${BUILDPATH}/target_token/Applications/Utilities
|
||||
mv ${BUILDPATH}/target_token/Applications/OpenSCTokenApp.app ${BUILDPATH}/target_token/Applications/Utilities
|
||||
xcodebuild -target OpenSCTokenApp -configuration Debug -project OpenSCTokenApp.xcodeproj install DSTROOT=${BUILDPATH}/target_token \
|
||||
CODE_SIGN_IDENTITY="${CODE_SIGN_IDENTITY}" DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}" OTHER_CODE_SIGN_FLAGS="--timestamp --options=runtime" CODE_SIGN_INJECT_BASE_ENTITLEMENTS=NO CODE_SIGN_STYLE=Manual
|
||||
cd ..
|
||||
|
||||
COMPONENT_TOKEN="--component-plist MacOSX/target_token.plist"
|
||||
else
|
||||
# if no OpenSCToken is checked out, then we create a dummy package
|
||||
mkdir -p ${BUILDPATH}/target_token
|
||||
fi
|
||||
|
||||
if test -n "${CODE_SIGN_IDENTITY}"; then
|
||||
for d in ${BUILDPATH}/target/Library/OpenSC/bin ${BUILDPATH}/target/Library/OpenSC/lib
|
||||
do
|
||||
# find executable files and run codesign on them
|
||||
find ${d} -type f -perm +111 -print -exec \
|
||||
codesign --force --sign "${CODE_SIGN_IDENTITY}" --entitlements MacOSX/OpenSC_binaries.entitlements --deep --timestamp --options runtime {} \;
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
# Build package
|
||||
pkgbuild --root ${BUILDPATH}/target --scripts MacOSX/scripts --identifier org.opensc-project.mac --version @PACKAGE_VERSION@ --install-location / OpenSC.pkg
|
||||
pkgbuild --root ${BUILDPATH}/target_tokend --identifier org.opensc-project.tokend --version @PACKAGE_VERSION@ --install-location / OpenSC-tokend.pkg
|
||||
pkgbuild --root ${BUILDPATH}/target_token --identifier org.opensc-project.mac.opensctoken --version @PACKAGE_VERSION@ --install-location / OpenSCToken.pkg
|
||||
pkgbuild --root ${BUILDPATH}/target_startup --identifier org.opensc-project.startup --version @PACKAGE_VERSION@ --install-location / OpenSC-startup.pkg
|
||||
pkgbuild --root ${BUILDPATH}/target --component-plist MacOSX/target.plist --scripts MacOSX/scripts --identifier org.opensc-project.mac --version @PACKAGE_VERSION@ --install-location / OpenSC.pkg
|
||||
pkgbuild --root ${BUILDPATH}/target_tokend --component-plist MacOSX/target_tokend.plist --identifier org.opensc-project.tokend --version @PACKAGE_VERSION@ --install-location / OpenSC-tokend.pkg
|
||||
pkgbuild --root ${BUILDPATH}/target_token $COMPONENT_TOKEN --identifier org.opensc-project.mac.opensctoken --version @PACKAGE_VERSION@ --install-location / OpenSCToken.pkg
|
||||
pkgbuild --root ${BUILDPATH}/target_startup --component-plist MacOSX/target_startup.plist --identifier org.opensc-project.startup --version @PACKAGE_VERSION@ --install-location / OpenSC-startup.pkg
|
||||
|
||||
# Build product
|
||||
productbuild --distribution MacOSX/Distribution.xml --package-path . --resources MacOSX/resources "${imagedir}/OpenSC @PACKAGE_VERSION@.pkg"
|
||||
|
||||
# Sign installer
|
||||
if test -n "${INSTALLER_SIGN_IDENTITY}"; then
|
||||
productsign --sign "${INSTALLER_SIGN_IDENTITY}" "${imagedir}/OpenSC @PACKAGE_VERSION@.pkg" "${BUILDPATH}/OpenSC @PACKAGE_VERSION@.pkg"
|
||||
mv "${BUILDPATH}/OpenSC @PACKAGE_VERSION@.pkg" "${imagedir}/OpenSC @PACKAGE_VERSION@.pkg"
|
||||
fi
|
||||
|
||||
# Build "Uninstaller"
|
||||
osacompile -o "${imagedir}/OpenSC Uninstaller.app" "MacOSX/OpenSC_Uninstaller.applescript"
|
||||
if test -n "${CODE_SIGN_IDENTITY}"; then
|
||||
codesign --force --sign "${CODE_SIGN_IDENTITY}" --entitlements MacOSX/OpenSC_applescripts.entitlements --deep --timestamp --options runtime "${imagedir}/OpenSC Uninstaller.app"
|
||||
fi
|
||||
|
||||
# Create .dmg
|
||||
rm -f OpenSC-@PACKAGE_VERSION@.dmg
|
||||
rm -f OpenSC-@PACKAGE_VERSION@$TOKEND.dmg
|
||||
i=0
|
||||
while ! hdiutil create -srcfolder "${imagedir}" -volname "@PACKAGE_NAME@" -fs JHFS+ OpenSC-@PACKAGE_VERSION@.dmg
|
||||
while ! hdiutil create -srcfolder "${imagedir}" -volname "@PACKAGE_NAME@" -fs JHFS+ OpenSC-@PACKAGE_VERSION@$TOKEND.dmg
|
||||
do
|
||||
i=$[$i+1]
|
||||
if [ $i -gt 2 ]
|
||||
|
@ -205,3 +246,6 @@ do
|
|||
fi
|
||||
done
|
||||
rm -rf ${imagedir}
|
||||
|
||||
#if [ "$TRAVIS_EVENT_TYPE" != "pull_request" ]; then xcrun altool --notarize-app --file $(pwd)/vorteil_darwin-x86.dmg --username $OSX_NOTARIZE_USERNAME --primary-bundle-id com.vorteil.cli -p $OSX_NOTARIZE_PW -- >> /dev/null; fi;
|
||||
#if [ "$TRAVIS_EVENT_TYPE" != "pull_request" ]; then for ((i=1;i<=30;i+=1)); do xcrun stapler staple $(pwd)/vorteil_darwin-x86.dmg >> /dev/null; if [ $? = 65 ]; then echo "Waiting for notarization to complete..." && sleep 10; fi; done; fi;
|
||||
|
|
|
@ -53,8 +53,8 @@ done
|
|||
|
||||
# register the launch agents
|
||||
for f in \
|
||||
/Library/LaunchAgents/pkcs11-register.plist \
|
||||
/Library/LaunchAgents/opensc-notify.plist
|
||||
/Library/LaunchAgents/org.opensc-project.mac.pkcs11-register.plist \
|
||||
/Library/LaunchAgents/org.opensc-project.mac.opensc-notify.plist
|
||||
do
|
||||
[ -e "$f" ] || continue
|
||||
/bin/launchctl asuser "$(id -u "$USER")" /bin/launchctl load "$f" || true
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<array>
|
||||
<dict>
|
||||
<key>BundleHasStrictIdentifier</key>
|
||||
<true/>
|
||||
<key>BundleIsRelocatable</key>
|
||||
<false/>
|
||||
<key>BundleIsVersionChecked</key>
|
||||
<true/>
|
||||
<key>BundleOverwriteAction</key>
|
||||
<string>upgrade</string>
|
||||
<key>RootRelativeBundlePath</key>
|
||||
<string>Library/OpenSC/Applications/NotificationProxy.app</string>
|
||||
</dict>
|
||||
</array>
|
||||
</plist>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<array/>
|
||||
</plist>
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<array>
|
||||
<dict>
|
||||
<key>BundleHasStrictIdentifier</key>
|
||||
<true/>
|
||||
<key>BundleIsRelocatable</key>
|
||||
<false/>
|
||||
<key>BundleIsVersionChecked</key>
|
||||
<true/>
|
||||
<key>BundleOverwriteAction</key>
|
||||
<string>upgrade</string>
|
||||
<key>ChildBundles</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>BundleOverwriteAction</key>
|
||||
<string></string>
|
||||
<key>RootRelativeBundlePath</key>
|
||||
<string>Applications/Utilities/OpenSCTokenApp.app/Contents/PlugIns/OpenSCToken.appex</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>RootRelativeBundlePath</key>
|
||||
<string>Applications/Utilities/OpenSCTokenApp.app</string>
|
||||
</dict>
|
||||
</array>
|
||||
</plist>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<array/>
|
||||
</plist>
|
55
NEWS
55
NEWS
|
@ -1,7 +1,49 @@
|
|||
NEWS for OpenSC -- History of user visible changes
|
||||
|
||||
# New in 0.21.0; 2020-XX-XX
|
||||
# New in 0.22.0; 2021-08-10
|
||||
## General improvements
|
||||
* Use standard paths for file cache on Linux (#2148) and OSX (#2214)
|
||||
* Various issues of memory/buffer handling in legacy drivers mostly reported by oss-fuzz and coverity (tcos, oberthur, isoapplet, iasecc, westcos, gpk, flex, dnie, mcrd, authentic, belpic)
|
||||
* Add threading test to `pkcs11-tool` (#2067)
|
||||
* Add support to generate generic secret keys (#2140)
|
||||
* `opensc-explorer`: Print information about LCS (Life cycle status byte) (#2195)
|
||||
* Add support for Apple's arm64 (M1) binaries, removed TokenD. A seperate installer with TokenD (and without arm64 binaries) will be available (#2179).
|
||||
* Support for gcc11 and its new strict aliasing rules (#2241, #2260)
|
||||
* Initial support for building with OpenSSL 3.0 (#2343)
|
||||
* pkcs15-tool: Write data objects in binary mode (#2324)
|
||||
* Avoid limited size of log messages (#2352)
|
||||
## PKCS#11
|
||||
* Support for ECDSA verification (#2211)
|
||||
* Support for ECDSA with different SHA hashes (#2190)
|
||||
* Prevent issues in p11-kit by not returning unexpected return codes (#2207)
|
||||
* Add support for PKCS#11 3.0: The new interfaces, profile objects and functions (#2096, #2293)
|
||||
* Standardize the version 2 on 2.20 in the code (#2096)
|
||||
* Fix CKA_MODIFIABLE and CKA_EXTRACTABLE (#2176)
|
||||
* Copy arguments of C_Initialize (#2350)
|
||||
## Minidriver
|
||||
* Fix RSA-PSS signing (#2234)
|
||||
## OpenPGP
|
||||
* Fix DO deletion (#2215)
|
||||
* Add support for (X)EdDSA keys (#1960)
|
||||
## IDPrime
|
||||
* Add support for applet version 3 and fix RSA-PSS mechanisms (#2205)
|
||||
* Add support for applet version 4 (#2332)
|
||||
## MyEID
|
||||
* New configuration option for opensc.conf to disable pkcs1_padding (#2193)
|
||||
* Add support for ECDSA with different hashes (#2190)
|
||||
* Enable more mechanisms (#2178)
|
||||
* Fixed asking for a user pin when formatting a card (#1737)
|
||||
## IAS/ECC
|
||||
* Added support for French CPx Healthcare cards (#2217)
|
||||
## CardOS
|
||||
* Added ATR for new CardOS 5.4 version (#2296)
|
||||
|
||||
# New in 0.21.0; 2020-11-24
|
||||
## General Improvements
|
||||
* fixed security problems
|
||||
* CVE-2020-26570 (6903aebfddc466d966c7b865fae34572bf3ed23e)
|
||||
* CVE-2020-26571
|
||||
* CVE-2020-26572 (9d294de90d1cc66956389856e60b6944b27b4817)
|
||||
* Bump minimal required OpenSSL version to 1.0.1 (#1658)
|
||||
* Implement basic unit tests for asn1 library, compression and simpletlv parser (#1830)
|
||||
* Allow generating code coverage
|
||||
|
@ -15,8 +57,11 @@ NEWS for OpenSC -- History of user visible changes
|
|||
## PKCS#11
|
||||
* Return CKR_TOKEN_NOT_RECOGNIZED for not recognized cards (#2030)
|
||||
* Propagate ignore_user_content to PKCS#11 layer not to confuse applications (#2040)
|
||||
## Minidriver
|
||||
* Fix check of ATR length (2-to 33 characters inclusive) (#2146)
|
||||
## MacOS
|
||||
* Add installer signing for PR and master
|
||||
* Avoid app bundle relocations after installation
|
||||
* Move OpenSC to MacOS Utilities folder (#2063)
|
||||
## OpenSC tools
|
||||
### pkcs11-tool
|
||||
|
@ -38,6 +83,11 @@ NEWS for OpenSC -- History of user visible changes
|
|||
## ePass2003
|
||||
* Improve ECC support (#1859)
|
||||
* Fixed erase sequence (#2097)
|
||||
## IAS-ECC (#2070):
|
||||
* Fixed support for Idemia Cosmo cards with AWP middleware interoperability (previously broken).
|
||||
* Added support for Idemia Cosmo v8 cards.
|
||||
* PIN padding settings are now used from PKCS#15 info when available.
|
||||
* Added PIN-pad support for PIN unblock.
|
||||
## IDPrime
|
||||
* New driver for Gemalto IDPrime (only some types) (#1772)
|
||||
## eDo
|
||||
|
@ -48,6 +98,9 @@ NEWS for OpenSC -- History of user visible changes
|
|||
* Add missing encryption certificates (#2083)
|
||||
## PIV
|
||||
* Add ATR of DOD Yubikey (#2115)
|
||||
* fixed PIV global pin bug (#2142)
|
||||
## CAC1
|
||||
* Support changing PIN with CAC Alt tokens (#2129)
|
||||
|
||||
# New in 0.20.0; 2019-12-29
|
||||
## General Improvements
|
||||
|
|
17
README.md
17
README.md
|
@ -4,7 +4,8 @@ Wiki is [available online](https://github.com/OpenSC/OpenSC/wiki)
|
|||
|
||||
Please take a look at the documentation before trying to use OpenSC.
|
||||
|
||||
[![Travis CI Build Status](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches)
|
||||
[![Linux build](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml)
|
||||
[![OSX build](https://github.com/OpenSC/OpenSC/actions/workflows/macos.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/macos.yml)
|
||||
[![AppVeyor CI Build Status](https://ci.appveyor.com/api/projects/status/github/OpenSC/OpenSC?branch=master&svg=true)](https://ci.appveyor.com/project/LudovicRousseau/OpenSC/branch/master)
|
||||
[![Coverity Scan Status](https://scan.coverity.com/projects/4026/badge.svg)](https://scan.coverity.com/projects/4026)
|
||||
[![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/OpenSC/OpenSC.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/OpenSC/OpenSC/context:cpp)
|
||||
|
@ -15,11 +16,11 @@ Build and test status of specific cards:
|
|||
|
||||
| Cards | Status |
|
||||
|---------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------|
|
||||
| CAC | [![CAC](https://gitlab.com/redhat-crypto/OpenSC/badges/cac/pipeline.svg)](https://gitlab.com/redhat-crypto/OpenSC/pipelines) |
|
||||
| [virt_CACard](https://github.com/PL4typus/virt_cacard) | [![virt_CACard](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) |
|
||||
| CAC | [![CAC](https://gitlab.com/redhat-crypto/OpenSC/badges/cac/pipeline.svg)](https://gitlab.com/redhat-crypto/OpenSC/pipelines) |
|
||||
| [virt_CACard](https://github.com/Jakuje/virt_cacard) | [![virt_CACard](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml) |
|
||||
| [Coolkey](https://github.com/dogtagpki/coolkey/tree/master/applet) | [![Coolkey](https://gitlab.com/redhat-crypto/OpenSC/badges/coolkey/pipeline.svg)](https://gitlab.com/redhat-crypto/OpenSC/pipelines) |
|
||||
| [PivApplet](https://github.com/arekinath/PivApplet) | [![PIV](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) |
|
||||
| [OpenPGP Applet](https://github.com/Yubico/ykneo-openpgp/) | [![OpenPGP](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) |
|
||||
| [GidsApplet](https://github.com/vletoux/GidsApplet/) | [![GIDS](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) |
|
||||
| [IsoApplet](https://github.com/philipWendland/IsoApplet/) | [![IsoApplet](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) |
|
||||
| [OsEID (MyEID)](https://sourceforge.net/projects/oseid/) | [![OsEID (MyEID)](https://travis-ci.org/OpenSC/OpenSC.svg)](https://travis-ci.org/OpenSC/OpenSC/branches) |
|
||||
| [PivApplet](https://github.com/arekinath/PivApplet) | [![PIV](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml) |
|
||||
| [OpenPGP Applet](https://github.com/Yubico/ykneo-openpgp/) | [![OpenPGP](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml) |
|
||||
| [GidsApplet](https://github.com/vletoux/GidsApplet/) | [![GIDS](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml) |
|
||||
| [IsoApplet](https://github.com/philipWendland/IsoApplet/) | [![IsoApplet](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml) |
|
||||
| [OsEID (MyEID)](https://sourceforge.net/projects/oseid/) | [![OsEID (MyEID)](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml/badge.svg)](https://github.com/OpenSC/OpenSC/actions/workflows/linux.yml) |
|
||||
|
|
12
appveyor.yml
12
appveyor.yml
|
@ -1,4 +1,4 @@
|
|||
version: 0.21.0.{build}
|
||||
version: 0.22.0.{build}
|
||||
|
||||
platform:
|
||||
- x86
|
||||
|
@ -12,7 +12,7 @@ environment:
|
|||
GH_TOKEN:
|
||||
secure: aLu3tFc7lRJbotnmnHLx/QruIHc5rLaGm1RttoEdy4QILlPXzVkCZ6loYMz0sfrY
|
||||
PATH: C:\cygwin\bin;%PATH%
|
||||
OPENPACE_VER: 1.1.0
|
||||
OPENPACE_VER: 1.1.1
|
||||
ZLIB_VER_DOT: 1.2.11
|
||||
matrix:
|
||||
# not compatible with OpenSSL 1.1.1:
|
||||
|
@ -59,12 +59,12 @@ install:
|
|||
Rename-Item -path "c:\openpace-${env:OPENPACE_VER}" -newName "openpace"
|
||||
}
|
||||
}
|
||||
If (!(Test-Path cngsdk.msi )) {
|
||||
appveyor DownloadFile "http://download.microsoft.com/download/2/C/9/2C93059C-0532-42DF-8C24-9AEAFF00768E/cngsdk.msi"
|
||||
If (!(Test-Path cpdksetup.exe )) {
|
||||
appveyor DownloadFile "https://download.microsoft.com/download/1/7/6/176909B0-50F2-4DF3-B29B-830A17EA7E38/CPDK_RELEASE_UPDATE/cpdksetup.exe"
|
||||
}
|
||||
- echo "Using %APPVEYOR_BUILD_WORKER_IMAGE% with %VCVARSALL%"
|
||||
- call "%VCVARSALL%" %Platform%
|
||||
- cngsdk.msi /quiet
|
||||
- cpdksetup.exe /quiet
|
||||
- uname -a
|
||||
- set
|
||||
|
||||
|
@ -126,4 +126,4 @@ cache:
|
|||
- C:\openpace -> appveyor.yml
|
||||
- C:\openpace-Win32 -> appveyor.yml
|
||||
- C:\openpace-Win64 -> appveyor.yml
|
||||
- cngsdk.msi -> appveyor.yml
|
||||
- cpdksetup.exe -> appveyor.yml
|
||||
|
|
26
configure.ac
26
configure.ac
|
@ -1,15 +1,15 @@
|
|||
dnl -*- mode: m4; -*-
|
||||
|
||||
AC_PREREQ(2.60)
|
||||
AC_PREREQ(2.68)
|
||||
|
||||
define([PRODUCT_NAME], [OpenSC])
|
||||
define([PRODUCT_TARNAME], [opensc])
|
||||
define([PRODUCT_BUGREPORT], [https://github.com/OpenSC/OpenSC/issues])
|
||||
define([PRODUCT_URL], [https://github.com/OpenSC/OpenSC])
|
||||
define([PACKAGE_VERSION_MAJOR], [0])
|
||||
define([PACKAGE_VERSION_MINOR], [21])
|
||||
define([PACKAGE_VERSION_MINOR], [22])
|
||||
define([PACKAGE_VERSION_FIX], [0])
|
||||
define([PACKAGE_SUFFIX], [-rc1])
|
||||
define([PACKAGE_SUFFIX], [])
|
||||
|
||||
define([VS_FF_LEGAL_COPYRIGHT], [OpenSC Project])
|
||||
define([VS_FF_LEGAL_COMPANY_NAME], [OpenSC Project])
|
||||
|
@ -43,10 +43,10 @@ OPENSC_VS_FF_PRODUCT_URL="VS_FF_PRODUCT_URL"
|
|||
|
||||
# LT Version numbers, remember to change them just *before* a release.
|
||||
# (Code changed: REVISION++)
|
||||
# (Oldest interface removed: OLDEST++)
|
||||
# (Oldest interface changed/removed: OLDEST++)
|
||||
# (Interfaces added: CURRENT++, REVISION=0)
|
||||
OPENSC_LT_CURRENT="6"
|
||||
OPENSC_LT_OLDEST="6"
|
||||
OPENSC_LT_CURRENT="8"
|
||||
OPENSC_LT_OLDEST="8"
|
||||
OPENSC_LT_REVISION="0"
|
||||
OPENSC_LT_AGE="0"
|
||||
OPENSC_LT_AGE="$((${OPENSC_LT_CURRENT}-${OPENSC_LT_OLDEST}))"
|
||||
|
@ -133,7 +133,7 @@ esac
|
|||
|
||||
AX_CODE_COVERAGE()
|
||||
|
||||
AX_CHECK_COMPILE_FLAG([-Wunknown-warning-option], [have_unknown_warning_option="yes"], [have_unknown_warning_option="no"], [-Werror])
|
||||
AX_CHECK_COMPILE_FLAG([-Wunknown-warning-option], [have_unknown_warning_option="yes"], [have_unknown_warning_option="no"])
|
||||
AM_CONDITIONAL([HAVE_UNKNOWN_WARNING_OPTION], [test "${have_unknown_warning_option}" = "yes"])
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
|
@ -188,7 +188,7 @@ AC_ARG_ENABLE(
|
|||
)
|
||||
|
||||
AC_ARG_ENABLE([openssl-secure-malloc],
|
||||
[AC_HELP_STRING([--openssl-secure-malloc=<SIZE_IN_BYTES>],
|
||||
[AS_HELP_STRING([--openssl-secure-malloc=<SIZE_IN_BYTES>],
|
||||
[Enable OpenSSL secure memory by specifying its size in bytes, must be a power of 2 @<:@disabled@:>@])],
|
||||
[], [enable_openssl_secure_malloc=no])
|
||||
AS_IF([test $enable_openssl_secure_malloc != no],
|
||||
|
@ -394,7 +394,6 @@ dnl C Compiler features
|
|||
AC_C_INLINE
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_HEADER_SYS_WAIT
|
||||
AC_HEADER_ASSERT
|
||||
AC_CHECK_HEADERS([ \
|
||||
|
@ -408,7 +407,6 @@ dnl Checks for typedefs, structures, and compiler characteristics.
|
|||
AC_C_CONST
|
||||
AC_TYPE_UID_T
|
||||
AC_TYPE_SIZE_T
|
||||
AC_HEADER_TIME
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_FUNC_ERROR_AT_LINE
|
||||
|
@ -729,7 +727,7 @@ LIBS="$saved_LIBS"
|
|||
|
||||
|
||||
AC_ARG_ENABLE(cvcdir,
|
||||
AC_HELP_STRING([--enable-cvcdir=DIR],
|
||||
AS_HELP_STRING([--enable-cvcdir=DIR],
|
||||
[directory containing CV certificates (default is determined by libeac)]),
|
||||
[cvcdir="${enableval}"],
|
||||
[cvcdir=false])
|
||||
|
@ -751,7 +749,7 @@ AC_SUBST(CVCDIR)
|
|||
AC_DEFINE_UNQUOTED([CVCDIR], ["${CVCDIR}"], [CVC directory])
|
||||
|
||||
AC_ARG_ENABLE(x509dir,
|
||||
AC_HELP_STRING([--enable-x509dir=DIR],
|
||||
AS_HELP_STRING([--enable-x509dir=DIR],
|
||||
[directory containing X.509 certificates (default is determined by libeac)]),
|
||||
[x509dir="${enableval}"],
|
||||
[x509dir=false])
|
||||
|
@ -953,6 +951,7 @@ AC_PATH_PROG(GENGETOPT, gengetopt, not found)
|
|||
AC_ARG_VAR([CLANGTIDY],
|
||||
[absolute path to clang-tidy used for static code analysis])
|
||||
AC_PATH_PROG(CLANGTIDY, clang-tidy, not found)
|
||||
TIDY_CHECKS="-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling"
|
||||
|
||||
AX_FUNC_GETOPT_LONG
|
||||
#AH_BOTTOM([#include "common/compat_getopt.h"])
|
||||
|
@ -1060,6 +1059,7 @@ AC_SUBST([PROFILE_DIR])
|
|||
AC_SUBST([PROFILE_DIR_DEFAULT])
|
||||
AC_SUBST([OPTIONAL_NOTIFY_CFLAGS])
|
||||
AC_SUBST([OPTIONAL_NOTIFY_LIBS])
|
||||
AC_SUBST([TIDY_CHECKS])
|
||||
|
||||
AM_CONDITIONAL([ENABLE_MAN], [test "${enable_man}" = "yes"])
|
||||
AM_CONDITIONAL([ENABLE_THREAD_LOCKING], [test "${enable_thread_locking}" = "yes"])
|
||||
|
@ -1089,7 +1089,7 @@ if test "${enable_pedantic}" = "yes"; then
|
|||
CFLAGS="-pedantic ${CFLAGS}"
|
||||
fi
|
||||
if test "${enable_strict}" = "yes"; then
|
||||
CFLAGS="-Wall -Wextra -Wno-unused-parameter -Werror ${CFLAGS}"
|
||||
CFLAGS="-Wall -Wextra -Wno-unused-parameter -Werror -Wstrict-aliasing=2 ${CFLAGS}"
|
||||
fi
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
|
|
|
@ -10,7 +10,7 @@ man5_MANS = pkcs15-profile.5 opensc.conf.5
|
|||
endif
|
||||
|
||||
opensc.conf.5.xml opensc.conf.5: $(srcdir)/opensc.conf.5.xml.in
|
||||
sed \
|
||||
@sed \
|
||||
-e 's|@sysconfdir[@]|$(sysconfdir)|g' \
|
||||
-e 's|@docdir[@]|$(docdir)|g' \
|
||||
-e 's|@libdir[@]|$(libdir)|g' \
|
||||
|
@ -19,14 +19,14 @@ opensc.conf.5.xml opensc.conf.5: $(srcdir)/opensc.conf.5.xml.in
|
|||
-e 's|@PROFILE_DIR_DEFAULT[@]|$(PROFILE_DIR_DEFAULT)|g' \
|
||||
-e 's|@DEFAULT_SM_MODULE[@]|$(DEFAULT_SM_MODULE)|g' \
|
||||
< $< > opensc.conf.5.xml
|
||||
$(XSLTPROC) --nonet --path "$(srcdir)/..:$(xslstylesheetsdir)/manpages" --xinclude -o $@ man.xsl opensc.conf.5.xml
|
||||
$(AM_V_GEN)$(XSLTPROC) --nonet --path "$(srcdir)/..:$(xslstylesheetsdir)/manpages" --xinclude -o $@ man.xsl opensc.conf.5.xml 2>/dev/null
|
||||
|
||||
files.html: $(srcdir)/files.xml $(wildcard $(srcdir)/*.5.xml) opensc.conf.5.xml
|
||||
$(XSLTPROC) --nonet --path "$(builddir):$(srcdir)/..:$(xslstylesheetsdir)/html" --xinclude -o $@ html.xsl $<
|
||||
$(AM_V_GEN)$(XSLTPROC) --nonet --path "$(builddir):$(srcdir)/..:$(xslstylesheetsdir)/html" --xinclude -o $@ html.xsl $< 2>/dev/null
|
||||
|
||||
%.5: $(srcdir)/%.5.xml
|
||||
sed -e 's|@pkgdatadir[@]|$(pkgdatadir)|g' < $< \
|
||||
| $(XSLTPROC) --nonet --path "$(srcdir)/..:$(xslstylesheetsdir)/manpages" --xinclude -o $@ man.xsl $<
|
||||
$(AM_V_GEN)sed -e 's|@pkgdatadir[@]|$(pkgdatadir)|g' < $< \
|
||||
| $(XSLTPROC) --nonet --path "$(srcdir)/..:$(xslstylesheetsdir)/manpages" --xinclude -o $@ man.xsl $< 2>/dev/null
|
||||
|
||||
clean-local:
|
||||
-rm -rf $(html_DATA) $(man5_MANS) opensc.conf.5.xml
|
||||
|
|
|
@ -43,7 +43,7 @@ span.errortext {
|
|||
font-style: italic;
|
||||
}
|
||||
|
||||
--></style></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book"><div class="titlepage"><div><div><h1 class="title"><a name="idm1"></a>OpenSC Manual Pages: Section 5</h1></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="refentrytitle"><a href="#opensc.conf">opensc.conf</a></span><span class="refpurpose"> — configuration file for OpenSC</span></dt><dt><span class="refentrytitle"><a href="#pkcs15-profile">pkcs15-profile</a></span><span class="refpurpose"> — format of profile for <span class="command"><strong>pkcs15-init</strong></span></span></dt></dl></div><div class="refentry"><a name="opensc.conf"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>opensc.conf — configuration file for OpenSC</p></div><div class="refsect1"><a name="idm13"></a><h2>Description</h2><p>
|
||||
--></style></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book"><div class="titlepage"><div><div><h1 class="title"><a name="id-1"></a>OpenSC Manual Pages: Section 5</h1></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl class="toc"><dt><span class="refentrytitle"><a href="#opensc.conf">opensc.conf</a></span><span class="refpurpose"> — configuration file for OpenSC</span></dt><dt><span class="refentrytitle"><a href="#pkcs15-profile">pkcs15-profile</a></span><span class="refpurpose"> — format of profile for <span class="command"><strong>pkcs15-init</strong></span></span></dt></dl></div><div class="refentry"><a name="opensc.conf"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>opensc.conf — configuration file for OpenSC</p></div><div class="refsect1"><a name="id-1.2.3"></a><h2>Description</h2><p>
|
||||
OpenSC obtains configuration data from the following sources in the following order
|
||||
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
|
||||
command-line options
|
||||
|
@ -122,7 +122,7 @@ app <em class="replaceable"><code>application</code></em> {
|
|||
<code class="literal">westcos-tool</code>:
|
||||
Configuration block for OpenSC tools
|
||||
</p></li></ul></div><p>
|
||||
</p></div><div class="refsect1"><a name="idm103"></a><h2>Configuration Options</h2><div class="variablelist"><dl class="variablelist"><dt><a name="debug"></a><span class="term">
|
||||
</p></div><div class="refsect1"><a name="id-1.2.4"></a><h2>Configuration Options</h2><div class="variablelist"><dl class="variablelist"><dt><a name="debug"></a><span class="term">
|
||||
<code class="option">debug = <em class="replaceable"><code>num</code></em>;</code>
|
||||
</span></dt><dd><p>
|
||||
Amount of debug info to print (Default:
|
||||
|
@ -153,6 +153,12 @@ app <em class="replaceable"><code>application</code></em> {
|
|||
<code class="filename">Software\OpenSC
|
||||
Project\OpenSC\ProfileDir</code> is
|
||||
checked.
|
||||
</p></dd><dt><span class="term">
|
||||
<code class="option">disable_colors = <em class="replaceable"><code>bool</code></em>;</code>
|
||||
</span></dt><dd><p>
|
||||
Disable colors of log messages (Default:
|
||||
<code class="literal">false</code> if attached to a console,
|
||||
<code class="literal">true</code> otherwise).
|
||||
</p></dd><dt><span class="term">
|
||||
<code class="option">disable_popups = <em class="replaceable"><code>bool</code></em>;</code>
|
||||
</span></dt><dd><p>
|
||||
|
@ -176,7 +182,7 @@ app <em class="replaceable"><code>application</code></em> {
|
|||
default) will load all statically linked drivers.
|
||||
</p><p>
|
||||
If an unknown (i.e. not internal or old) driver is
|
||||
supplied, a separate configuration configuration
|
||||
supplied, a separate configuration
|
||||
block has to be written for the driver. A special
|
||||
value <code class="literal">old</code> will load all
|
||||
statically linked drivers that may be removed in
|
||||
|
@ -227,6 +233,10 @@ app <em class="replaceable"><code>application</code></em> {
|
|||
<code class="literal">npa</code>: See <a class="xref" href="#npa" title="Configuration Options for German ID Card">the section called “Configuration Options for German ID Card”</a>
|
||||
</p></li><li class="listitem"><p>
|
||||
<code class="literal">dnie</code>: See <a class="xref" href="#dnie" title="Configuration Options for DNIe">the section called “Configuration Options for DNIe”</a>
|
||||
</p></li><li class="listitem"><p>
|
||||
<code class="literal">edo</code>: See <a class="xref" href="#edo" title="Configuration Options for Polish eID Card">the section called “Configuration Options for Polish eID Card”</a>
|
||||
</p></li><li class="listitem"><p>
|
||||
<code class="literal">myeid</code>: See <a class="xref" href="#myeid" title="Configuration Options for MyEID Card">the section called “Configuration Options for MyEID Card”</a>
|
||||
</p></li><li class="listitem"><p>
|
||||
Any other value: Configuration block for an externally loaded card driver
|
||||
</p></li></ul></div><p>
|
||||
|
@ -332,7 +342,7 @@ app <em class="replaceable"><code>application</code></em> {
|
|||
Parameters for the OpenSC PKCS11 module.
|
||||
</p><p>
|
||||
For details see <a class="xref" href="#pkcs11" title="Configuration of PKCS#11">the section called “Configuration of PKCS#11”</a>.
|
||||
</p></dd></dl></div><div class="refsect2"><a name="reader_driver"></a><h3>Configuration of Smart Card Reader Driver</h3><div class="refsect3"><a name="idm330"></a><h4>Configuration Options for all Reader Drivers</h4><div class="variablelist"><dl class="variablelist"><dt><span class="term">
|
||||
</p></dd></dl></div><div class="refsect2"><a name="reader_driver"></a><h3>Configuration of Smart Card Reader Driver</h3><div class="refsect3"><a name="id-1.2.4.3.2"></a><h4>Configuration Options for all Reader Drivers</h4><div class="variablelist"><dl class="variablelist"><dt><span class="term">
|
||||
<code class="option">max_send_size = <em class="replaceable"><code>num</code></em>;</code>
|
||||
<code class="option">max_recv_size = <em class="replaceable"><code>num</code></em>;</code>
|
||||
</span></dt><dd><p>
|
||||
|
@ -429,7 +439,27 @@ app <em class="replaceable"><code>application</code></em> {
|
|||
<code class="option">readers = <em class="replaceable"><code>num</code></em>;</code>
|
||||
</span></dt><dd><p>
|
||||
Virtual readers to allocate (Default: <code class="literal">2</code>).
|
||||
</p></dd></dl></div></div></div><div class="refsect2"><a name="npa"></a><h3>Configuration Options for German ID Card</h3><div class="variablelist"><dl class="variablelist"><dt><span class="term">
|
||||
</p></dd></dl></div></div></div><div class="refsect2"><a name="myeid"></a><h3>Configuration Options for MyEID Card</h3><div class="variablelist"><dl class="variablelist"><dt><span class="term">
|
||||
<code class="option">disable_hw_pkcs1_padding = <em class="replaceable"><code>bool</code></em>;</code>
|
||||
</span></dt><dd><p>
|
||||
The MyEID card can internally
|
||||
encapsulate the data (hash code)
|
||||
into a DigestInfo ASN.1 structure
|
||||
according to the selected hash
|
||||
algorithm (currently only for SHA1).
|
||||
DigestInfo is padded to RSA key
|
||||
modulus length according to PKCS#1
|
||||
v1.5, block type 01h. Size of the
|
||||
DigestInfo must not exceed 40%
|
||||
of the RSA key modulus length. If
|
||||
this limit is unsatisfactory (for
|
||||
example someone needs RSA 1024
|
||||
with SHA512), the user can disable
|
||||
this feature. In this case, the
|
||||
card driver will do everything
|
||||
necessary before sending the data
|
||||
(hash code) to the card.
|
||||
</p></dd></dl></div></div><div class="refsect2"><a name="npa"></a><h3>Configuration Options for German ID Card</h3><div class="variablelist"><dl class="variablelist"><dt><span class="term">
|
||||
<code class="option">can = <em class="replaceable"><code>value</code></em>;</code>
|
||||
</span></dt><dd><p>
|
||||
German ID card requires the CAN to
|
||||
|
@ -478,6 +508,16 @@ app <em class="replaceable"><code>application</code></em> {
|
|||
<code class="literal">/usr/bin/pinentry</code>).
|
||||
Only used if compiled with
|
||||
<code class="option">--enable-dnie-ui</code>
|
||||
</p></dd></dl></div></div><div class="refsect2"><a name="edo"></a><h3>Configuration Options for Polish eID Card</h3><div class="variablelist"><dl class="variablelist"><dt><span class="term">
|
||||
<code class="option">can = <em class="replaceable"><code>value</code></em>;</code>
|
||||
</span></dt><dd><p>
|
||||
CAN (Card Access Number – 6 digit number
|
||||
printed on the right bottom corner of the
|
||||
front side of the document) is required
|
||||
to establish connection with the card.
|
||||
It might be overwritten by <code class="literal">EDO_CAN</code>
|
||||
environment variable. Currently, it is not
|
||||
possible to set it in any other way.
|
||||
</p></dd></dl></div></div><div class="refsect2"><a name="card_atr"></a><h3>Configuration based on ATR</h3><p>
|
||||
</p><div class="variablelist"><dl class="variablelist"><dt><span class="term">
|
||||
<code class="option">atrmask = <em class="replaceable"><code>hexstring</code></em>;</code>
|
||||
|
@ -554,10 +594,10 @@ app <em class="replaceable"><code>application</code></em> {
|
|||
<code class="literal">raw</code>
|
||||
</p></li></ul></div><p>
|
||||
</p></dd><dt><span class="term">
|
||||
<code class="option">md_read_only = <em class="replaceable"><code>bool</code></em>;</code>
|
||||
<code class="option">read_only = <em class="replaceable"><code>bool</code></em>;</code>
|
||||
</span></dt><dd><p>
|
||||
Mark card as read/only card in
|
||||
Minidriver/BaseCSP interface
|
||||
PKCS#11/Minidriver/BaseCSP interface
|
||||
(Default: <code class="literal">false</code>).
|
||||
</p></dd><dt><span class="term">
|
||||
<code class="option">md_supports_X509_enrollment = <em class="replaceable"><code>bool</code></em>;</code>
|
||||
|
@ -724,9 +764,11 @@ app <em class="replaceable"><code>application</code></em> {
|
|||
</span></dt><dd><p>
|
||||
Where to cache the card's files. The default values are:
|
||||
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
|
||||
<code class="filename"><code class="envar">HOME</code>/.eid/cache/</code> (Unix)
|
||||
<code class="filename"><code class="envar">$XDG_CACHE_HOME</code>/opensc/</code> (If <code class="envar">$XDG_CACHE_HOME</code> is defined)
|
||||
</p></li><li class="listitem"><p>
|
||||
<code class="filename"><code class="envar">USERPROFILE</code>\.eid-cache\</code> (Windows)
|
||||
<code class="filename"><code class="envar">$HOME</code>/.cache/opensc/</code> (Unix)
|
||||
</p></li><li class="listitem"><p>
|
||||
<code class="filename"><code class="envar">$USERPROFILE</code>\.eid-cache\</code> (Windows)
|
||||
</p></li></ul></div><p>
|
||||
</p><p>
|
||||
If caching is done by a system process, the
|
||||
|
@ -753,6 +795,26 @@ app <em class="replaceable"><code>application</code></em> {
|
|||
<code class="literal">CKA_ALWAYS_AUTHENTICATE</code> may
|
||||
need to set this to get signatures to work with
|
||||
some cards (Default: <code class="literal">false</code>).
|
||||
</p><p>
|
||||
It is recommended to enable also PIN caching using
|
||||
<code class="literal">use_pin_caching</code> option for OpenSC
|
||||
to be able to provide PIN for the card when needed.
|
||||
</p></dd><dt><span class="term">
|
||||
<code class="option">private_certificate = <em class="replaceable"><code>value</code></em>;</code>
|
||||
</span></dt><dd><p>
|
||||
How to handle a PIN-protected certificate. Known
|
||||
parameters:
|
||||
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
|
||||
<code class="literal">protect</code>: The certificate stays PIN-protected.
|
||||
</p></li><li class="listitem"><p>
|
||||
<code class="literal">declassify</code>: Allow
|
||||
reading the certificate without
|
||||
enforcing verification of the PIN.
|
||||
</p></li><li class="listitem"><p>
|
||||
<code class="literal">ignore</code>: Ignore PIN-protected certificates.
|
||||
</p></li></ul></div><p>
|
||||
(Default: <code class="literal">ignore</code> in Tokend,
|
||||
<code class="literal">protect</code> otherwise).
|
||||
</p></dd><dt><span class="term">
|
||||
<code class="option">enable_pkcs15_emulation = <em class="replaceable"><code>bool</code></em>;</code>
|
||||
</span></dt><dd><p>
|
||||
|
@ -775,7 +837,7 @@ app <em class="replaceable"><code>application</code></em> {
|
|||
<code class="option">builtin_emulators = <em class="replaceable"><code>emulators</code></em>;</code>
|
||||
</span></dt><dd><p>
|
||||
List of the builtin pkcs15 emulators to test
|
||||
(Default: <code class="literal">westcos, openpgp,
|
||||
(Default: <code class="literal">westcos, openpgp,
|
||||
starcert, tcos, esteid, itacns,
|
||||
PIV-II, cac, gemsafeGPK, gemsafeV1, actalis,
|
||||
atrust-acos, tccardos, entersafe, pteid,
|
||||
|
@ -854,13 +916,6 @@ app <em class="replaceable"><code>application</code></em> {
|
|||
Score for <span class="application">OpenSC.tokend</span>
|
||||
(Default: <code class="literal">300</code>). The tokend with
|
||||
the highest score shall be used.
|
||||
</p></dd><dt><span class="term">
|
||||
<code class="option">ignore_private_certificate = <em class="replaceable"><code>bool</code></em>;</code>
|
||||
</span></dt><dd><p>
|
||||
Tokend ignore to read PIN protected certificate
|
||||
that is set
|
||||
<code class="literal">SC_PKCS15_CO_FLAG_PRIVATE</code> flag
|
||||
(Default: <code class="literal">true</code>).
|
||||
</p></dd></dl></div></div><div class="refsect2"><a name="pkcs11"></a><h3>Configuration of PKCS#11</h3><div class="variablelist"><dl class="variablelist"><dt><span class="term">
|
||||
<code class="option">max_virtual_slots = <em class="replaceable"><code>num</code></em>;</code>
|
||||
</span></dt><dd><p>
|
||||
|
@ -1020,7 +1075,7 @@ app <em class="replaceable"><code>application</code></em> {
|
|||
For the module to simulate the opensc-onepin module
|
||||
behavior the following option
|
||||
<code class="option">create_slots_for_pins = "user";</code>
|
||||
</p></dd></dl></div></div></div><div class="refsect1"><a name="idm971"></a><h2>Environment</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term">
|
||||
</p></dd></dl></div></div></div><div class="refsect1"><a name="id-1.2.5"></a><h2>Environment</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term">
|
||||
<code class="envar">OPENSC_CONF</code>
|
||||
</span></dt><dd><p>
|
||||
Filename for a user defined configuration file
|
||||
|
@ -1063,7 +1118,7 @@ app <em class="replaceable"><code>application</code></em> {
|
|||
</span></dt><dd><p>
|
||||
PIV configuration during initialization with
|
||||
<span class="application">piv-tool</span>.
|
||||
</p></dd></dl></div></div><div class="refsect1"><a name="idm1012"></a><h2>Files</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term">
|
||||
</p></dd></dl></div></div><div class="refsect1"><a name="id-1.2.6"></a><h2>Files</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term">
|
||||
<code class="filename">/usr/etc/opensc.conf</code>
|
||||
</span></dt><dd><p>
|
||||
System-wide configuration file
|
||||
|
@ -1071,7 +1126,7 @@ app <em class="replaceable"><code>application</code></em> {
|
|||
<code class="filename">/usr/share/doc/opensc/opensc.conf</code>
|
||||
</span></dt><dd><p>
|
||||
Extended example configuration file
|
||||
</p></dd></dl></div></div></div><div class="refentry"><div class="refentry.separator"><hr></div><a name="pkcs15-profile"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>pkcs15-profile — format of profile for <span class="command"><strong>pkcs15-init</strong></span></p></div><div class="refsect1"><a name="idm1036"></a><h2>Description</h2><p>
|
||||
</p></dd></dl></div></div></div><div class="refentry"><div class="refentry.separator"><hr></div><a name="pkcs15-profile"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>pkcs15-profile — format of profile for <span class="command"><strong>pkcs15-init</strong></span></p></div><div class="refsect1"><a name="id-1.3.3"></a><h2>Description</h2><p>
|
||||
The <span class="command"><strong>pkcs15-init</strong></span> utility for PKCS #15 smart card
|
||||
personalization is controlled via profiles. When starting, it will read two
|
||||
such profiles at the moment, a generic application profile, and a card
|
||||
|
@ -1087,10 +1142,10 @@ app <em class="replaceable"><code>application</code></em> {
|
|||
The card specific profile contains additional information required during
|
||||
card initialization, such as location of PIN files, key references etc.
|
||||
Profiles currently reside in <code class="filename">@pkgdatadir@</code>
|
||||
</p></div><div class="refsect1"><a name="idm1044"></a><h2>Syntax</h2><p>
|
||||
</p></div><div class="refsect1"><a name="id-1.3.4"></a><h2>Syntax</h2><p>
|
||||
This section should contain information about the profile syntax. Will add
|
||||
this soonishly.
|
||||
</p></div><div class="refsect1"><a name="idm1047"></a><h2>See also</h2><p>
|
||||
</p></div><div class="refsect1"><a name="id-1.3.5"></a><h2>See also</h2><p>
|
||||
<span class="citerefentry"><span class="refentrytitle">pkcs15-init</span>(1)</span>,
|
||||
<span class="citerefentry"><span class="refentrytitle">pkcs15-crypt</span>(1)</span>
|
||||
</p></div></div></div></body></html>
|
||||
|
|
|
@ -296,6 +296,9 @@ app <replaceable>application</replaceable> {
|
|||
<listitem><para>
|
||||
<literal>edo</literal>: See <xref linkend="edo"/>
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<literal>myeid</literal>: See <xref linkend="myeid"/>
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Any other value: Configuration block for an externally loaded card driver
|
||||
</para></listitem>
|
||||
|
@ -639,6 +642,37 @@ app <replaceable>application</replaceable> {
|
|||
|
||||
</refsect2>
|
||||
|
||||
<refsect2 id="myeid">
|
||||
<title>Configuration Options for MyEID Card</title>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>disable_hw_pkcs1_padding = <replaceable>bool</replaceable>;</option>
|
||||
</term>
|
||||
<listitem><para>
|
||||
The MyEID card can internally
|
||||
encapsulate the data (hash code)
|
||||
into a DigestInfo ASN.1 structure
|
||||
according to the selected hash
|
||||
algorithm (currently only for SHA1).
|
||||
DigestInfo is padded to RSA key
|
||||
modulus length according to PKCS#1
|
||||
v1.5, block type 01h. Size of the
|
||||
DigestInfo must not exceed 40%
|
||||
of the RSA key modulus length. If
|
||||
this limit is unsatisfactory (for
|
||||
example someone needs RSA 1024
|
||||
with SHA512), the user can disable
|
||||
this feature. In this case, the
|
||||
card driver will do everything
|
||||
necessary before sending the data
|
||||
(hash code) to the card.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</refsect2>
|
||||
|
||||
<refsect2 id="npa">
|
||||
<title>Configuration Options for German ID Card</title>
|
||||
<variablelist>
|
||||
|
@ -1116,12 +1150,17 @@ app <replaceable>application</replaceable> {
|
|||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<filename><envar>HOME</envar>/.eid/cache/</filename> (Unix)
|
||||
<filename><envar>$XDG_CACHE_HOME</envar>/opensc/</filename> (If <envar>$XDG_CACHE_HOME</envar> is defined)
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<filename><envar>USERPROFILE</envar>\.eid-cache\</filename> (Windows)
|
||||
<filename><envar>$HOME</envar>/.cache/opensc/</filename> (Unix)
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<filename><envar>$USERPROFILE</envar>\.eid-cache\</filename> (Windows)
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
|
|
@ -14,15 +14,14 @@ endif
|
|||
completion_DATA = $(patsubst $(srcdir)/%.1.xml, %, $(wildcard $(srcdir)/*.1.xml))
|
||||
|
||||
tools.html: $(srcdir)/tools.xml $(wildcard $(srcdir)/*.1.xml)
|
||||
$(XSLTPROC) --nonet --path "$(srcdir)/..:$(xslstylesheetsdir)/html" --xinclude -o $@ html.xsl $<
|
||||
$(AM_V_GEN)$(XSLTPROC) --nonet --path "$(srcdir)/..:$(xslstylesheetsdir)/html" --xinclude -o $@ html.xsl $< 2>/dev/null
|
||||
|
||||
%.1: $(srcdir)/%.1.xml
|
||||
sed -e 's|@pkgdatadir[@]|$(pkgdatadir)|g' < $< \
|
||||
| $(XSLTPROC) --nonet --path "$(srcdir)/..:$(xslstylesheetsdir)/manpages" --xinclude -o $@ man.xsl $<
|
||||
$(AM_V_GEN)sed -e 's|@pkgdatadir[@]|$(pkgdatadir)|g' < $< \
|
||||
| $(XSLTPROC) --nonet --path "$(srcdir)/..:$(xslstylesheetsdir)/manpages" --xinclude -o $@ man.xsl $< 2>/dev/null
|
||||
|
||||
%: $(srcdir)/%.1.xml
|
||||
@echo $< $@
|
||||
@cat $(srcdir)/completion-template \
|
||||
$(AM_V_GEN)cat $(srcdir)/completion-template \
|
||||
| sed "s,ALLOPTS,\
|
||||
$(shell sed -n 's,.*<option>\([^<]*\)</option>.*,\1,pg' $< \
|
||||
| sort -u | grep -- '^\-' | tr '\n' ' ')," \
|
||||
|
|
|
@ -53,15 +53,18 @@
|
|||
<option>--admin</option> <replaceable>argument</replaceable>,
|
||||
<option>-A</option> <replaceable>argument</replaceable>
|
||||
</term>
|
||||
<listitem><para>Authenticate to the card using a 2DES or 3DES key.
|
||||
<listitem><para>Authenticate to the card using a 2DES, 3DES or AES key.
|
||||
The <replaceable>argument</replaceable> of the form
|
||||
<synopsis> {<literal>A</literal>|<literal>M</literal>}<literal>:</literal><replaceable>ref</replaceable><literal>:</literal><replaceable>alg</replaceable></synopsis>
|
||||
is required, were <literal>A</literal> uses "EXTERNAL AUTHENTICATION"
|
||||
and <literal>M</literal> uses "MUTUAL AUTHENTICATION".
|
||||
<replaceable>ref</replaceable> is normally <literal>9B</literal>,
|
||||
and <replaceable>alg</replaceable> is <literal>03</literal> for 3DES.
|
||||
The key is provided by the card vendor, and the environment variable
|
||||
<varname>PIV_EXT_AUTH_KEY</varname> must point to a text file containing
|
||||
and <replaceable>alg</replaceable> is <literal>03</literal> for 3DES,
|
||||
<literal>01</literal> for 2DES, <literal>08</literal> for AES-128,
|
||||
<literal>0A</literal> for AES-192 or <literal>0C</literal> for AES-256.
|
||||
The key is provided by the card vendor. The environment variable
|
||||
<varname>PIV_EXT_AUTH_KEY</varname> must point to either a binary file
|
||||
matching the length of the key or a text file containing
|
||||
the key in the format:
|
||||
<code>XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX</code>
|
||||
</para></listitem>
|
||||
|
|
|
@ -146,7 +146,9 @@
|
|||
<term>
|
||||
<option>--key-type</option> <replaceable>specification</replaceable>
|
||||
</term>
|
||||
<listitem><para>Specify the type and length of the key to create, for example rsa:1024 or EC:prime256v1.</para></listitem>
|
||||
<listitem><para>Specify the type and length (bytes if symmetric) of the key to create,
|
||||
for example RSA:1024, EC:prime256v1, GOSTR3410-2012-256:B,
|
||||
DES:8, DES3:24, AES:16 or GENERIC:64.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
|
@ -219,6 +221,13 @@
|
|||
<listitem><para>List slots with tokens.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--list-interfaces</option>
|
||||
</term>
|
||||
<listitem><para>List interfaces of PKCS #11 3.0 library.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--login</option>,
|
||||
|
@ -417,6 +426,22 @@
|
|||
<listitem><para>Specify the index of the object to use.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--use-locking</option>
|
||||
</term>
|
||||
<listitem><para>Tell pkcs11 module it should use OS thread locking.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--test-threads</option> <replaceable>options</replaceable>
|
||||
</term>
|
||||
<listitem><para>Test a pkcs11 module's thread implication. (See source code).
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--token-label</option> <replaceable>label</replaceable>
|
||||
|
|
|
@ -136,11 +136,12 @@
|
|||
<command>pkcs15-init --generate-key " keyspec " --auth-id " nn</command>
|
||||
</para>
|
||||
<para>
|
||||
where <replaceable>keyspec</replaceable> describes the algorithm and length of the
|
||||
key to be created, such as <literal>rsa/512</literal>. This will create a 512 bit
|
||||
RSA key. Currently, only RSA key generation is supported. Note that cards
|
||||
usually support just a few different key lengths. Almost all cards will support
|
||||
512 and 1024 bit keys, some will support 768 or 2048 as well.
|
||||
where <replaceable>keyspec</replaceable> describes the algorithm and the parameters
|
||||
of the key to be created. For example, <literal>rsa:2048</literal> generates a RSA key
|
||||
with 2048-bit modulus. If you are generating an EC key, the curve designation must
|
||||
be specified, for example <literal>ec:prime256v1</literal>. For symmetric key,
|
||||
the length of key is specified in bytes, for example <literal>AES:32</literal>
|
||||
or <literal>DES3:24</literal>.
|
||||
</para>
|
||||
<para>
|
||||
<replaceable>nn</replaceable> is the ID of a user PIN installed previously,
|
||||
|
@ -242,7 +243,7 @@
|
|||
you would use
|
||||
</para>
|
||||
<para>
|
||||
<command>pkcs15-init --store-secret-key /dev/urandom --secret-key-algorithm aes/256 --auth-id 01</command>
|
||||
<command>pkcs15-init --store-secret-key /dev/urandom --secret-key-algorithm aes:256 --auth-id 01</command>
|
||||
</para>
|
||||
<para>
|
||||
By default a random ID is generated for the secret key. You may specify an ID
|
||||
|
@ -332,9 +333,9 @@
|
|||
<listitem>
|
||||
<para>
|
||||
Tells the card to generate new key and store it on the card.
|
||||
<replaceable>keyspec</replaceable> consists of an algorithm name
|
||||
(currently, the only supported name is <option>RSA</option>),
|
||||
optionally followed by a slash and the length of the key in bits.
|
||||
<replaceable>keyspec</replaceable> consists of an algorithm name,
|
||||
optionally followed by a colon ":", slash "/" or hyphen "-" and
|
||||
the parameters of the key to be created.
|
||||
It is a good idea to specify the key ID along with this command,
|
||||
using the <option>id</option> option, otherwise an intrinsic ID
|
||||
will be calculated from the key material. Look the description of
|
||||
|
@ -417,7 +418,7 @@
|
|||
<listitem>
|
||||
<para>
|
||||
<replaceable>keyspec</replaceable> describes the algorithm and length of the
|
||||
key to be created or downloaded, such as <literal>aes/256</literal>.
|
||||
key to be created or downloaded, such as <literal>aes:256</literal>.
|
||||
This will create a 256 bit AES key.
|
||||
</para>
|
||||
</listitem>
|
||||
|
|
1032
doc/tools/tools.html
1032
doc/tools/tools.html
File diff suppressed because it is too large
Load Diff
|
@ -17,7 +17,7 @@ force:
|
|||
opensc.conf.example: opensc.conf.example.in force
|
||||
|
||||
.in:
|
||||
@sed \
|
||||
$(AM_V_GEN)sed \
|
||||
-e 's|@pkgdatadir[@]|$(pkgdatadir)|g' \
|
||||
-e 's|@DEBUG_FILE[@]|$(DEBUG_FILE)|g' \
|
||||
-e 's|@DEFAULT_PCSC_PROVIDER[@]|$(DEFAULT_PCSC_PROVIDER)|g' \
|
||||
|
|
|
@ -43,4 +43,4 @@ TIDY_FILES = \
|
|||
libpkcs11.c libscdl.c
|
||||
|
||||
check-local:
|
||||
if [ -x "$(CLANGTIDY)" ]; then clang-tidy -config='' -header-filter=.* $(TIDY_FILES) -- $(TIDY_FLAGS); fi
|
||||
if [ -x "$(CLANGTIDY)" ]; then clang-tidy -config='' --checks='$(TIDY_CHECKS)' -header-filter=.* $(addprefix $(srcdir)/,$(TIDY_FILES)) -- $(TIDY_FLAGS); fi
|
||||
|
|
|
@ -49,6 +49,7 @@ C_LoadModule(const char *mspec, CK_FUNCTION_LIST_PTR_PTR funcs)
|
|||
{
|
||||
sc_pkcs11_module_t *mod;
|
||||
CK_RV rv, (*c_get_function_list)(CK_FUNCTION_LIST_PTR_PTR);
|
||||
CK_RV (*c_get_interface)(CK_UTF8CHAR_PTR, CK_VERSION_PTR, CK_INTERFACE_PTR_PTR, CK_FLAGS);
|
||||
mod = calloc(1, sizeof(*mod));
|
||||
if (mod == NULL) {
|
||||
return NULL;
|
||||
|
@ -65,6 +66,24 @@ C_LoadModule(const char *mspec, CK_FUNCTION_LIST_PTR_PTR funcs)
|
|||
goto failed;
|
||||
}
|
||||
|
||||
c_get_interface = (CK_RV (*)(CK_UTF8CHAR_PTR, CK_VERSION_PTR, CK_INTERFACE_PTR_PTR, CK_FLAGS))
|
||||
sc_dlsym(mod->handle, "C_GetInterface");
|
||||
if (c_get_interface) {
|
||||
CK_INTERFACE *interface = NULL;
|
||||
|
||||
/* Get default PKCS #11 interface */
|
||||
rv = c_get_interface((CK_UTF8CHAR_PTR) "PKCS 11", NULL, &interface, 0);
|
||||
if (rv == CKR_OK) {
|
||||
/* this is actually 3.0 function list, but it starts
|
||||
* with the same fields. Only for new functions, it
|
||||
* needs to be casted to new structure */
|
||||
*funcs = interface->pFunctionList;
|
||||
return (void *) mod;
|
||||
} else {
|
||||
fprintf(stderr, "C_GetInterface failed %lx, retry 2.x way", rv);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the list of function pointers */
|
||||
c_get_function_list = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR))
|
||||
sc_dlsym(mod->handle, "C_GetFunctionList");
|
||||
|
|
|
@ -28,7 +28,9 @@
|
|||
#if !defined(_WIN32)
|
||||
#include <arpa/inet.h> /* for htons() */
|
||||
#include <unistd.h>
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h> /* for gettimeofday() */
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#include <winsock2.h>
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
/build/
|
|
@ -0,0 +1,12 @@
|
|||
cmake_minimum_required(VERSION 3.18)
|
||||
|
||||
project(gcns VERSION 1.0 DESCRIPTION "Italian healthcare smart card parsing utility")
|
||||
|
||||
add_library(gcns SHARED gcns.c gcns.cpp)
|
||||
target_include_directories(gcns PUBLIC ../.. .. .)
|
||||
install(TARGETS gcns LIBRARY)
|
||||
install(FILES gcns.h gcns.hpp DESTINATION include)
|
||||
|
||||
add_executable(main main.c ../tools/util.c)
|
||||
target_link_libraries(main gcns opensc bsd)
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
# Maintainer: Giovan Battista Rolandi <giomba@linux.it>
|
||||
|
||||
pkgname=gcns
|
||||
pkgver=1.0
|
||||
pkgrel=1
|
||||
pkgdesc='Tools for Italian healthcare smart card'
|
||||
arch=('x86_64')
|
||||
url='https://git.golem.linux.it/giomba/opensc'
|
||||
license=('LGPL')
|
||||
depends=('opensc')
|
||||
source=('git+https://git.golem.linux.it/giomba/opensc#branch=golem/tessera-sanitaria')
|
||||
sha256sums=('SKIP')
|
||||
|
||||
build() {
|
||||
cd opensc
|
||||
|
||||
./bootstrap
|
||||
./configure
|
||||
make -j$(nproc)
|
||||
cd src/gcns
|
||||
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake ..
|
||||
make -j$(nproc)
|
||||
|
||||
}
|
||||
|
||||
package() {
|
||||
cd opensc/src/gcns/build
|
||||
make DESTDIR=$pkgdir install
|
||||
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* gcns.c: A reader of Italian healtcare smartcards with libopensc
|
||||
*
|
||||
* Copyright (C) 2022 Giovan Battista Rolandi <giomba@linux.it>
|
||||
* based on previous work by
|
||||
* Copyright (C) 2001 Juha Yrjölä <juha.yrjola@iki.fi>
|
||||
*
|
||||
* This library 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.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "gcns.h"
|
||||
|
||||
#include "libopensc/asn1.h"
|
||||
#include "tools/util.h"
|
||||
|
||||
static int opt_wait = 0;
|
||||
static const char *opt_reader = NULL;
|
||||
static sc_context_t *ctx = NULL;
|
||||
static sc_card_t *card = NULL;
|
||||
sc_context_param_t ctx_param;
|
||||
|
||||
int gcns_init() {
|
||||
int r, err = 0;
|
||||
int lcycle = SC_CARDCTRL_LIFECYCLE_ADMIN;
|
||||
|
||||
memset(&ctx_param, 0, sizeof(ctx_param));
|
||||
ctx_param.ver = 0;
|
||||
|
||||
r = sc_context_create(&ctx, &ctx_param);
|
||||
if (r) {
|
||||
fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(r));
|
||||
return GCNS_INIT;
|
||||
}
|
||||
|
||||
ctx->flags |= SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER;
|
||||
|
||||
err = util_connect_card_ex(ctx, &card, opt_reader, opt_wait, 0, 0);
|
||||
if (err) {
|
||||
return GCNS_INIT;
|
||||
}
|
||||
|
||||
r = sc_lock(card);
|
||||
if (r == SC_SUCCESS)
|
||||
r = sc_card_ctl(card, SC_CARDCTL_LIFECYCLE_SET, &lcycle);
|
||||
sc_unlock(card);
|
||||
if (r && r != SC_ERROR_NOT_SUPPORTED) {
|
||||
fprintf(stderr, "unable to change lifecycle: %s\n", sc_strerror(r));
|
||||
return GCNS_INIT;
|
||||
}
|
||||
|
||||
return GCNS_SUCCESS;
|
||||
}
|
||||
|
||||
int gcns_close() {
|
||||
if (card) {
|
||||
sc_disconnect_card(card);
|
||||
}
|
||||
if (ctx) sc_release_context(ctx);
|
||||
return GCNS_SUCCESS;
|
||||
}
|
||||
|
||||
int gcns_read_personal_data(u8 *buffer, size_t len) {
|
||||
sc_path_t path;
|
||||
int r;
|
||||
|
||||
sc_format_path("3F0011001102", &path);
|
||||
r = sc_select_file(card, &path, NULL);
|
||||
if (r) {
|
||||
fprintf(stderr, "no select file: 3F0011001102\n");
|
||||
return GCNS_READ_PERSONAL_DATA;
|
||||
}
|
||||
r = sc_read_binary(card, 0, buffer, 0x180, 0);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "no read binary: %d\n", r);
|
||||
return GCNS_READ_PERSONAL_DATA;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
#include "gcns.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
using namespace gcns;
|
||||
|
||||
PersonalData::PersonalData(const uint8_t* buffer, size_t len) {
|
||||
std::vector<std::string> field;
|
||||
|
||||
// TODO check length at the beginning?
|
||||
for (int i = 12; i < len;) {
|
||||
if (buffer[i] == '\0') break;
|
||||
|
||||
std::string hexstring((const char*)&buffer[i], 2);
|
||||
int len = std::stoi(hexstring, nullptr, 16);
|
||||
i += 2;
|
||||
std::string fieldData((const char*)&buffer[i], len);
|
||||
i += len;
|
||||
|
||||
field.push_back(fieldData);
|
||||
}
|
||||
|
||||
for (int i = 0; i < (int)field.size(); ++i) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
this->issue_date.year =
|
||||
std::stoi(field[i].substr(4, 4), nullptr);
|
||||
this->issue_date.month =
|
||||
std::stoi(field[i].substr(2, 2), nullptr);
|
||||
this->issue_date.day =
|
||||
std::stoi(field[i].substr(0, 2), nullptr);
|
||||
break;
|
||||
case 1:
|
||||
this->expiration_date.year =
|
||||
std::stoi(field[i].substr(4, 4), nullptr);
|
||||
this->expiration_date.month =
|
||||
std::stoi(field[i].substr(2, 2), nullptr);
|
||||
this->expiration_date.day =
|
||||
std::stoi(field[i].substr(0, 2), nullptr);
|
||||
break;
|
||||
case 2:
|
||||
this->family_name = field[i];
|
||||
break;
|
||||
case 3:
|
||||
this->first_name = field[i];
|
||||
break;
|
||||
case 4:
|
||||
this->birth_date.year =
|
||||
std::stoi(field[i].substr(4, 4), nullptr);
|
||||
this->birth_date.month =
|
||||
std::stoi(field[i].substr(2, 2), nullptr);
|
||||
this->birth_date.day =
|
||||
std::stoi(field[i].substr(0, 2), nullptr);
|
||||
break;
|
||||
case 5:
|
||||
this->gender = field[i] == "F" ? GENDER_FEMALE : GENDER_MALE;
|
||||
break;
|
||||
case 7:
|
||||
this->fiscal_code = field[i];
|
||||
break;
|
||||
case 9:
|
||||
this->birth_place = field[i];
|
||||
break;
|
||||
case 12:
|
||||
this->residence_place = field[i];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef GCNS_H
|
||||
#define GCNS_H
|
||||
|
||||
#define GCNS_SUCCESS 0
|
||||
#define GCNS_INIT -1001
|
||||
#define GCNS_READ_PERSONAL_DATA -1002
|
||||
#define GCNS_CLOSE -1003
|
||||
|
||||
int gcns_init();
|
||||
int gcns_read_personal_data(u8 *buffer, size_t len);
|
||||
int gcns_close();
|
||||
|
||||
#endif
|
|
@ -0,0 +1,34 @@
|
|||
#ifndef GCNS_CPP
|
||||
#define GCNS_CPP
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace gcns {
|
||||
|
||||
enum Gender { GENDER_MALE, GENDER_FEMALE };
|
||||
|
||||
struct Date {
|
||||
uint16_t year;
|
||||
uint8_t month;
|
||||
uint8_t day;
|
||||
};
|
||||
|
||||
class PersonalData {
|
||||
private:
|
||||
std::string first_name;
|
||||
std::string family_name;
|
||||
std::string fiscal_code;
|
||||
std::string birth_place;
|
||||
Date birth_date;
|
||||
std::string residence_place;
|
||||
Gender gender;
|
||||
Date issue_date;
|
||||
Date expiration_date;
|
||||
|
||||
public:
|
||||
PersonalData(const uint8_t* personal_data, size_t len);
|
||||
};
|
||||
|
||||
} // namespace gcns
|
||||
|
||||
#endif
|
|
@ -0,0 +1,56 @@
|
|||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "config.h"
|
||||
#ifdef ENABLE_READLINE
|
||||
#include <readline/history.h>
|
||||
#include <readline/readline.h>
|
||||
#endif
|
||||
#if !defined(_WIN32)
|
||||
#include <arpa/inet.h> /* for htons() */
|
||||
#endif
|
||||
|
||||
#include <getopt.h>
|
||||
|
||||
#include "common/compat_strlcpy.h"
|
||||
#include "gcns.h"
|
||||
#include "libopensc/asn1.h"
|
||||
#include "libopensc/cardctl.h"
|
||||
#include "libopensc/cards.h"
|
||||
#include "libopensc/internal.h"
|
||||
#include "libopensc/iso7816.h"
|
||||
#include "libopensc/log.h"
|
||||
#include "libopensc/opensc.h"
|
||||
#include "tools/util.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int r;
|
||||
|
||||
printf("OpenSC version: %s\n", sc_get_version());
|
||||
|
||||
r = gcns_init();
|
||||
if (r != GCNS_SUCCESS) {
|
||||
fprintf(stderr, "Init Error\n");
|
||||
return GCNS_INIT;
|
||||
}
|
||||
|
||||
u8 buffer[2048];
|
||||
r = gcns_read_personal_data(buffer, 2048);
|
||||
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "Read personal data error\n");
|
||||
return GCNS_READ_PERSONAL_DATA;
|
||||
}
|
||||
|
||||
util_hex_dump_asc(stdout, buffer, r, 0);
|
||||
|
||||
r = gcns_close();
|
||||
if (r != GCNS_SUCCESS) {
|
||||
return GCNS_CLOSE;
|
||||
}
|
||||
|
||||
return GCNS_SUCCESS;
|
||||
}
|
|
@ -147,4 +147,4 @@ TIDY_FILES = \
|
|||
#$(SOURCES)
|
||||
|
||||
check-local:
|
||||
if [ -x "$(CLANGTIDY)" ]; then clang-tidy -config='' -header-filter=.* $(TIDY_FILES) -- $(TIDY_FLAGS); fi
|
||||
if [ -x "$(CLANGTIDY)" ]; then clang-tidy -config='' --checks='$(TIDY_CHECKS)' -header-filter=.* $(addprefix $(srcdir)/,$(TIDY_FILES)) -- $(TIDY_FLAGS); fi
|
||||
|
|
|
@ -401,11 +401,13 @@ sc_set_le_and_transmit(struct sc_card *card, struct sc_apdu *apdu, size_t olen)
|
|||
/* set the new expected length */
|
||||
apdu->resplen = olen;
|
||||
apdu->le = nlen;
|
||||
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
/* Belpic V1 applets have a problem: if the card sends a 6C XX (only XX bytes available),
|
||||
* and we resend the command too soon (i.e. the reader is too fast), the card doesn't respond.
|
||||
* So we build in a delay. */
|
||||
if (card->type == SC_CARD_TYPE_BELPIC_EID)
|
||||
msleep(40);
|
||||
#endif
|
||||
|
||||
/* re-transmit the APDU with new Le length */
|
||||
rv = sc_single_transmit(card, apdu);
|
||||
|
|
|
@ -253,10 +253,15 @@ static void sc_asn1_print_bit_string(const u8 * buf, size_t buflen, size_t depth
|
|||
if (buflen > sizeof(a) + 1) {
|
||||
print_hex(buf, buflen, depth);
|
||||
} else {
|
||||
r = sc_asn1_decode_bit_string(buf, buflen, &a, sizeof(a));
|
||||
r = sc_asn1_decode_bit_string(buf, buflen, &a, sizeof(a), 1);
|
||||
if (r < 0) {
|
||||
printf("decode error");
|
||||
return;
|
||||
printf("decode error, ");
|
||||
/* try again without the strict mode */
|
||||
r = sc_asn1_decode_bit_string(buf, buflen, &a, sizeof(a), 0);
|
||||
if (r < 0) {
|
||||
printf("even for lax decoding");
|
||||
return ;
|
||||
}
|
||||
}
|
||||
for (i = r - 1; i >= 0; i--) {
|
||||
printf("%c", ((a >> i) & 1) ? '1' : '0');
|
||||
|
@ -567,7 +572,7 @@ const u8 *sc_asn1_verify_tag(sc_context_t *ctx, const u8 * buf, size_t buflen,
|
|||
}
|
||||
|
||||
static int decode_bit_string(const u8 * inbuf, size_t inlen, void *outbuf,
|
||||
size_t outlen, int invert)
|
||||
size_t outlen, int invert, const int strict)
|
||||
{
|
||||
const u8 *in = inbuf;
|
||||
u8 *out = (u8 *) outbuf;
|
||||
|
@ -577,13 +582,19 @@ static int decode_bit_string(const u8 * inbuf, size_t inlen, void *outbuf,
|
|||
|
||||
if (inlen < 1)
|
||||
return SC_ERROR_INVALID_ASN1_OBJECT;
|
||||
/* 8.6.2.3 If the bitstring is empty, there shall be no subsequent octets,
|
||||
* and the initial octet shall be zero. */
|
||||
if (inlen == 1 && *in != 0)
|
||||
return SC_ERROR_INVALID_ASN1_OBJECT;
|
||||
/* ITU-T Rec. X.690 8.6.2.2: The number shall be in the range zero to seven. */
|
||||
if ((*in & ~0x07) != 0)
|
||||
return SC_ERROR_INVALID_ASN1_OBJECT;
|
||||
|
||||
/* The formatting is only enforced by SHALL keyword so we should accept
|
||||
* by default also non-strict values. */
|
||||
if (strict) {
|
||||
/* 8.6.2.3 If the bitstring is empty, there shall be no
|
||||
* subsequent octets,and the initial octet shall be zero. */
|
||||
if (inlen == 1 && *in != 0)
|
||||
return SC_ERROR_INVALID_ASN1_OBJECT;
|
||||
/* ITU-T Rec. X.690 8.6.2.2: The number shall be in the range zero to seven. */
|
||||
if ((*in & ~0x07) != 0)
|
||||
return SC_ERROR_INVALID_ASN1_OBJECT;
|
||||
}
|
||||
|
||||
memset(outbuf, 0, outlen);
|
||||
zero_bits = *in & 0x07;
|
||||
in++;
|
||||
|
@ -622,15 +633,15 @@ static int decode_bit_string(const u8 * inbuf, size_t inlen, void *outbuf,
|
|||
}
|
||||
|
||||
int sc_asn1_decode_bit_string(const u8 * inbuf, size_t inlen,
|
||||
void *outbuf, size_t outlen)
|
||||
void *outbuf, size_t outlen, const int strict)
|
||||
{
|
||||
return decode_bit_string(inbuf, inlen, outbuf, outlen, 1);
|
||||
return decode_bit_string(inbuf, inlen, outbuf, outlen, 1, strict);
|
||||
}
|
||||
|
||||
int sc_asn1_decode_bit_string_ni(const u8 * inbuf, size_t inlen,
|
||||
void *outbuf, size_t outlen)
|
||||
void *outbuf, size_t outlen, const int strict)
|
||||
{
|
||||
return decode_bit_string(inbuf, inlen, outbuf, outlen, 0);
|
||||
return decode_bit_string(inbuf, inlen, outbuf, outlen, 0, strict);
|
||||
}
|
||||
|
||||
static int encode_bit_string(const u8 * inbuf, size_t bits_left, u8 **outbuf,
|
||||
|
@ -675,7 +686,7 @@ static int encode_bit_string(const u8 * inbuf, size_t bits_left, u8 **outbuf,
|
|||
* Bitfields are just bit strings, stored in an unsigned int
|
||||
* (taking endianness into account)
|
||||
*/
|
||||
static int decode_bit_field(const u8 * inbuf, size_t inlen, void *outbuf, size_t outlen)
|
||||
static int decode_bit_field(const u8 * inbuf, size_t inlen, void *outbuf, size_t outlen, const int strict)
|
||||
{
|
||||
u8 data[sizeof(unsigned int)];
|
||||
unsigned int field = 0;
|
||||
|
@ -684,7 +695,7 @@ static int decode_bit_field(const u8 * inbuf, size_t inlen, void *outbuf, size_t
|
|||
if (outlen != sizeof(data))
|
||||
return SC_ERROR_BUFFER_TOO_SMALL;
|
||||
|
||||
n = decode_bit_string(inbuf, inlen, data, sizeof(data), 1);
|
||||
n = decode_bit_string(inbuf, inlen, data, sizeof(data), 1, strict);
|
||||
if (n < 0)
|
||||
return n;
|
||||
|
||||
|
@ -1235,9 +1246,12 @@ static int asn1_decode_se_info(sc_context_t *ctx, const u8 *obj, size_t objlen,
|
|||
size_t idx, ptrlen = objlen;
|
||||
int ret;
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
|
||||
ses = calloc(SC_MAX_SE_NUM, sizeof(sc_pkcs15_sec_env_info_t *));
|
||||
if (ses == NULL)
|
||||
return SC_ERROR_OUT_OF_MEMORY;
|
||||
if (ses == NULL) {
|
||||
SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, SC_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
for (idx=0; idx < SC_MAX_SE_NUM && ptrlen; ) {
|
||||
struct sc_asn1_entry asn1_se[2];
|
||||
|
@ -1281,7 +1295,7 @@ err:
|
|||
free(ses);
|
||||
}
|
||||
|
||||
return ret;
|
||||
SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, ret);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1535,7 +1549,7 @@ static int asn1_decode_entry(sc_context_t *ctx,struct sc_asn1_entry *entry,
|
|||
*len = objlen-1;
|
||||
parm = *buf;
|
||||
}
|
||||
r = decode_bit_string(obj, objlen, (u8 *) parm, *len, invert);
|
||||
r = decode_bit_string(obj, objlen, (u8 *) parm, *len, invert, 0);
|
||||
if (r >= 0) {
|
||||
*len = r;
|
||||
r = 0;
|
||||
|
@ -1544,7 +1558,7 @@ static int asn1_decode_entry(sc_context_t *ctx,struct sc_asn1_entry *entry,
|
|||
break;
|
||||
case SC_ASN1_BIT_FIELD:
|
||||
if (parm != NULL)
|
||||
r = decode_bit_field(obj, objlen, (u8 *) parm, *len);
|
||||
r = decode_bit_field(obj, objlen, (u8 *) parm, *len, 0);
|
||||
break;
|
||||
case SC_ASN1_OCTET_STRING:
|
||||
if (parm != NULL) {
|
||||
|
@ -1988,6 +2002,10 @@ static int asn1_encode(sc_context_t *ctx, const struct sc_asn1_entry *asn1,
|
|||
u8 *obj = NULL, *buf = NULL, *tmp;
|
||||
size_t total = 0, objsize;
|
||||
|
||||
if (asn1 == NULL) {
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
}
|
||||
|
||||
for (idx = 0; asn1[idx].name != NULL; idx++) {
|
||||
r = asn1_encode_entry(ctx, &asn1[idx], &obj, &objsize, depth);
|
||||
if (r) {
|
||||
|
|
|
@ -96,10 +96,10 @@ void sc_asn1_print_tags(const u8 * buf, size_t buflen);
|
|||
int sc_asn1_utf8string_to_ascii(const u8 * buf, size_t buflen,
|
||||
u8 * outbuf, size_t outlen);
|
||||
int sc_asn1_decode_bit_string(const u8 * inbuf, size_t inlen,
|
||||
void *outbuf, size_t outlen);
|
||||
void *outbuf, size_t outlen, const int strict);
|
||||
/* non-inverting version */
|
||||
int sc_asn1_decode_bit_string_ni(const u8 * inbuf, size_t inlen,
|
||||
void *outbuf, size_t outlen);
|
||||
void *outbuf, size_t outlen, const int strict);
|
||||
int sc_asn1_decode_integer(const u8 * inbuf, size_t inlen, int *out, int strict);
|
||||
int sc_asn1_decode_object_id(const u8 * inbuf, size_t inlen,
|
||||
struct sc_object_id *id);
|
||||
|
@ -127,13 +127,16 @@ int sc_asn1_sig_value_sequence_to_rs(struct sc_context *ctx,
|
|||
const unsigned char *in, size_t inlen,
|
||||
unsigned char *buf, size_t buflen);
|
||||
|
||||
#define SC_ASN1_CLASS_MASK 0x30000000
|
||||
/* long form tags use these */
|
||||
/* Same as SC_ASN1_TAG_* shifted left by 24 bits */
|
||||
#define SC_ASN1_CLASS_MASK 0xC0000000
|
||||
#define SC_ASN1_UNI 0x00000000 /* Universal */
|
||||
#define SC_ASN1_APP 0x10000000 /* Application */
|
||||
#define SC_ASN1_CTX 0x20000000 /* Context */
|
||||
#define SC_ASN1_PRV 0x30000000 /* Private */
|
||||
#define SC_ASN1_CONS 0x01000000
|
||||
#define SC_ASN1_APP 0x40000000 /* Application */
|
||||
#define SC_ASN1_CTX 0x80000000 /* Context */
|
||||
#define SC_ASN1_PRV 0xC0000000 /* Private */
|
||||
#define SC_ASN1_CONS 0x20000000
|
||||
|
||||
#define SC_ASN1_CLASS_CONS 0xE0000000 /* CLASS and CONS */
|
||||
#define SC_ASN1_TAG_MASK 0x00FFFFFF
|
||||
#define SC_ASN1_TAGNUM_SIZE 3
|
||||
|
||||
|
@ -173,6 +176,7 @@ int sc_asn1_sig_value_sequence_to_rs(struct sc_context *ctx,
|
|||
/* use callback function */
|
||||
#define SC_ASN1_CALLBACK 384
|
||||
|
||||
/* use with short one byte tags */
|
||||
#define SC_ASN1_TAG_CLASS 0xC0
|
||||
#define SC_ASN1_TAG_UNIVERSAL 0x00
|
||||
#define SC_ASN1_TAG_APPLICATION 0x40
|
||||
|
@ -181,6 +185,7 @@ int sc_asn1_sig_value_sequence_to_rs(struct sc_context *ctx,
|
|||
|
||||
#define SC_ASN1_TAG_CONSTRUCTED 0x20
|
||||
#define SC_ASN1_TAG_PRIMITIVE 0x1F
|
||||
#define SC_ASN1_TAG_CLASS_CONS 0xE0
|
||||
|
||||
#define SC_ASN1_TAG_EOC 0
|
||||
#define SC_ASN1_TAG_BOOLEAN 1
|
||||
|
|
|
@ -672,12 +672,12 @@ authentic_reduce_path(struct sc_card *card, struct sc_path *path)
|
|||
cur_path = card->cache.current_df->path;
|
||||
|
||||
if (!memcmp(cur_path.value, "\x3F\x00", 2) && memcmp(in_path.value, "\x3F\x00", 2)) {
|
||||
memmove(in_path.value + 2, in_path.value, in_path.len);
|
||||
memmove(in_path.value + 2, in_path.value, (in_path.len - 2));
|
||||
memcpy(in_path.value, "\x3F\x00", 2);
|
||||
in_path.len += 2;
|
||||
}
|
||||
|
||||
for (offs=0; offs < in_path.len && offs < cur_path.len; offs += 2) {
|
||||
for (offs = 0; (offs + 1) < in_path.len && (offs + 1) < cur_path.len; offs += 2) {
|
||||
if (cur_path.value[offs] != in_path.value[offs])
|
||||
break;
|
||||
if (cur_path.value[offs + 1] != in_path.value[offs + 1])
|
||||
|
@ -699,8 +699,8 @@ authentic_debug_select_file(struct sc_card *card, const struct sc_path *path)
|
|||
struct sc_card_cache *cache = &card->cache;
|
||||
|
||||
if (path)
|
||||
sc_log(ctx, "try to select path(type:%i) %s",
|
||||
path->type, sc_print_path(path));
|
||||
sc_log(ctx, "try to select path(type:%i,len=%"SC_FORMAT_LEN_SIZE_T"u) %s",
|
||||
path->type, path->len, sc_print_path(path));
|
||||
|
||||
if (!cache->valid)
|
||||
return;
|
||||
|
@ -1558,6 +1558,7 @@ authentic_pin_reset(struct sc_card *card, struct sc_pin_cmd_data *data, int *tri
|
|||
pin_cmd.pin_type = data->pin_type;
|
||||
pin_cmd.pin1.tries_left = -1;
|
||||
|
||||
memset(&acls, 0, sizeof(acls));
|
||||
rv = authentic_pin_get_policy(card, &pin_cmd, acls);
|
||||
LOG_TEST_RET(ctx, rv, "Get 'PIN policy' error");
|
||||
|
||||
|
|
|
@ -215,7 +215,6 @@ static int belpic_match_card(sc_card_t *card)
|
|||
static int belpic_init(sc_card_t *card)
|
||||
{
|
||||
int key_size = 1024;
|
||||
int r;
|
||||
|
||||
sc_log(card->ctx, "Belpic V%s\n", BELPIC_VERSION);
|
||||
|
||||
|
@ -227,7 +226,7 @@ static int belpic_init(sc_card_t *card)
|
|||
u8 carddata[BELPIC_CARDDATA_RESP_LEN];
|
||||
memset(carddata, 0, sizeof(carddata));
|
||||
|
||||
if((r = get_carddata(card, carddata, sizeof(carddata))) < 0) {
|
||||
if(get_carddata(card, carddata, sizeof(carddata)) < 0) {
|
||||
return SC_ERROR_INVALID_CARD;
|
||||
}
|
||||
if (carddata[BELPIC_CARDDATA_OFF_APPLETVERS] >= 0x17) {
|
||||
|
|
|
@ -1793,7 +1793,7 @@ static int cac_find_and_initialize(sc_card_t *card, int initialize)
|
|||
}
|
||||
r = cac_process_ACA(card, priv);
|
||||
if (r == SC_SUCCESS) {
|
||||
card->type = SC_CARD_TYPE_CAC_II;
|
||||
card->type = SC_CARD_TYPE_CAC_ALT_HID;
|
||||
card->drv_data = priv;
|
||||
return r;
|
||||
}
|
||||
|
@ -1869,7 +1869,10 @@ static int cac_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries
|
|||
* FIPS 201 4.1.6.1 (numeric only) and * FIPS 140-2
|
||||
* (6 character minimum) requirements.
|
||||
*/
|
||||
sc_apdu_t apdu;
|
||||
u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
|
||||
struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
|
||||
int rv;
|
||||
|
||||
if (data->cmd == SC_PIN_CMD_CHANGE) {
|
||||
int i = 0;
|
||||
|
@ -1881,9 +1884,24 @@ static int cac_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries
|
|||
return SC_ERROR_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
/* We can change the PIN of Giesecke & Devrient CAC ALT tokens
|
||||
* with a bit non-standard APDU */
|
||||
if (card->type == SC_CARD_TYPE_CAC_ALT_HID) {
|
||||
int r = 0;
|
||||
r = iso7816_build_pin_apdu(card, &apdu, data, sbuf, sizeof(sbuf));
|
||||
if (r < 0)
|
||||
return r;
|
||||
/* it requires P1 = 0x01 completely against the ISO specs */
|
||||
apdu.p1 = 0x01;
|
||||
data->apdu = &apdu;
|
||||
}
|
||||
}
|
||||
|
||||
return iso_drv->ops->pin_cmd(card, data, tries_left);
|
||||
rv = iso_drv->ops->pin_cmd(card, data, tries_left);
|
||||
|
||||
data->apdu = NULL;
|
||||
return rv;
|
||||
}
|
||||
|
||||
static struct sc_card_operations cac_ops;
|
||||
|
|
|
@ -55,6 +55,8 @@ static const struct sc_atr_table cardos_atrs[] = {
|
|||
/* CardOS v5.3 */
|
||||
{ "3b:d2:18:00:81:31:fe:58:c9:02:17", NULL, NULL, SC_CARD_TYPE_CARDOS_V5_3, 0, NULL},
|
||||
{ "3b:d2:18:00:81:31:fe:58:c9:03:16", NULL, NULL, SC_CARD_TYPE_CARDOS_V5_3, 0, NULL},
|
||||
/* CardOS v5.4 */
|
||||
{ "3b:d2:18:00:81:31:fe:58:c9:04:11", NULL, NULL, SC_CARD_TYPE_CARDOS_V5_3, 0, NULL},
|
||||
{ NULL, NULL, NULL, 0, 0, NULL }
|
||||
};
|
||||
|
||||
|
@ -159,7 +161,7 @@ static int cardos_have_2048bit_package(sc_card_t *card)
|
|||
sc_apdu_t apdu;
|
||||
u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
|
||||
int r;
|
||||
const u8 *p = rbuf, *q;
|
||||
const u8 *p = rbuf, *q, *pp;
|
||||
size_t len, tlen = 0, ilen = 0;
|
||||
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, 0x88);
|
||||
|
@ -175,10 +177,10 @@ static int cardos_have_2048bit_package(sc_card_t *card)
|
|||
return 0;
|
||||
|
||||
while (len != 0) {
|
||||
p = sc_asn1_find_tag(card->ctx, p, len, 0xe1, &tlen);
|
||||
if (p == NULL)
|
||||
pp = sc_asn1_find_tag(card->ctx, p, len, 0xe1, &tlen);
|
||||
if (pp == NULL)
|
||||
return 0;
|
||||
q = sc_asn1_find_tag(card->ctx, p, tlen, 0x01, &ilen);
|
||||
q = sc_asn1_find_tag(card->ctx, pp, tlen, 0x01, &ilen);
|
||||
if (q == NULL || ilen != 4)
|
||||
return 0;
|
||||
if (q[0] == 0x1c)
|
||||
|
|
|
@ -2143,7 +2143,6 @@ static int dnie_pin_verify(struct sc_card *card,
|
|||
res = cwa_create_secure_channel(card, GET_DNIE_PRIV_DATA(card)->cwa_provider, CWA_SM_ON);
|
||||
LOG_TEST_RET(card->ctx, res, "Establish SM failed");
|
||||
|
||||
data->apdu = &apdu; /* prepare apdu struct */
|
||||
/* compose pin data to be inserted in apdu */
|
||||
if (data->flags & SC_PIN_CMD_NEED_PADDING)
|
||||
padding = 1;
|
||||
|
|
|
@ -948,7 +948,7 @@ decrypt_response(struct sc_card *card, unsigned char *in, size_t inlen, unsigned
|
|||
des3_decrypt_cbc(exdata->sk_enc, 16, iv, &in[i], cipher_len - 1, plaintext);
|
||||
|
||||
/* unpadding */
|
||||
while (0x80 != plaintext[cipher_len - 2] && (cipher_len - 2 > 0))
|
||||
while (0x80 != plaintext[cipher_len - 2] && (cipher_len > 2))
|
||||
cipher_len--;
|
||||
|
||||
if (2 == cipher_len || *out_len < cipher_len - 2)
|
||||
|
|
|
@ -815,7 +815,7 @@ cryptoflex_construct_file_attrs(sc_card_t *card, const sc_file_t *file,
|
|||
r = acl_to_keynum_nibble(entry);
|
||||
p[13 + i/2] |= (r & 0x0F) << (((i+1) % 2) * 4);
|
||||
}
|
||||
p[11] = (file->status & SC_FILE_STATUS_INVALIDATED) ? 0x00 : 0x01;
|
||||
p[11] = (file->status == SC_FILE_STATUS_INVALIDATED) ? 0x00 : 0x01;
|
||||
if (file->type != SC_FILE_TYPE_DF &&
|
||||
(file->ef_structure == SC_FILE_EF_LINEAR_FIXED ||
|
||||
file->ef_structure == SC_FILE_EF_CYCLIC))
|
||||
|
@ -1284,6 +1284,7 @@ static int flex_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data,
|
|||
r = iso_ops->pin_cmd(card, data, NULL);
|
||||
if (old_cla != -1)
|
||||
card->cla = old_cla;
|
||||
data->apdu = NULL;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -552,7 +552,9 @@ gpk_select_id(sc_card_t *card, int kind, unsigned int fid,
|
|||
cp->len = 0;
|
||||
/* fallthru */
|
||||
case GPK_SEL_DF:
|
||||
assert(cp->len + 1 <= SC_MAX_PATH_SIZE / 2);
|
||||
if (cp->len + 1 > SC_MAX_PATH_SIZE / 2) {
|
||||
return SC_ERROR_INTERNAL;
|
||||
}
|
||||
path = (unsigned short int *) cp->value;
|
||||
path[cp->len++] = fid;
|
||||
}
|
||||
|
@ -1795,7 +1797,10 @@ gpk_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left)
|
|||
|
||||
data->apdu = &apdu;
|
||||
|
||||
return iso_ops->pin_cmd(card, data, tries_left);
|
||||
r = iso_ops->pin_cmd(card, data, tries_left);
|
||||
|
||||
data->apdu = NULL;
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -95,6 +95,18 @@ static const struct sc_atr_table iasecc_known_atrs[] = {
|
|||
"IAS/ECC v1.0.1 Amos", SC_CARD_TYPE_IASECC_AMOS, 0, NULL },
|
||||
{ "3B:DC:18:FF:81:91:FE:1F:C3:80:73:C8:21:13:66:01:0B:03:52:00:05:38", NULL,
|
||||
"IAS/ECC v1.0.1 Amos", SC_CARD_TYPE_IASECC_AMOS, 0, NULL },
|
||||
{
|
||||
.atr = "3B:AC:00:40:2A:00:12:25:00:64:80:00:03:10:00:90:00",
|
||||
.atrmask = "FF:00:00:00:00:FF:FF:FF:FF:FF:FF:00:00:00:FF:FF:FF",
|
||||
.name = "IAS/ECC CPx",
|
||||
.type = SC_CARD_TYPE_IASECC_CPX,
|
||||
},
|
||||
{
|
||||
.atr = "2B:8F:80:01:00:31:B8:64:04:B0:EC:C1:73:94:01:80:82:90:00:0E",
|
||||
.atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:FF:C0:FF:FF:FF:FF:FF:FF:FF:FF",
|
||||
.name = "IAS/ECC CPxCL",
|
||||
.type = SC_CARD_TYPE_IASECC_CPXCL,
|
||||
},
|
||||
{ NULL, NULL, NULL, 0, 0, NULL }
|
||||
};
|
||||
|
||||
|
@ -310,12 +322,14 @@ iasecc_select_mf(struct sc_card *card, struct sc_file **file_out)
|
|||
mf_file->type = SC_FILE_TYPE_DF;
|
||||
mf_file->path = path;
|
||||
|
||||
if (card->cache.valid)
|
||||
sc_file_free(card->cache.current_df);
|
||||
if (card->cache.valid) {
|
||||
sc_file_free(card->cache.current_df);
|
||||
}
|
||||
card->cache.current_df = NULL;
|
||||
|
||||
if (card->cache.valid)
|
||||
if (card->cache.valid) {
|
||||
sc_file_free(card->cache.current_ef);
|
||||
}
|
||||
card->cache.current_ef = NULL;
|
||||
|
||||
sc_file_dup(&card->cache.current_df, mf_file);
|
||||
|
@ -337,6 +351,8 @@ iasecc_select_aid(struct sc_card *card, struct sc_aid *aid, unsigned char *out,
|
|||
unsigned char apdu_resp[SC_MAX_APDU_BUFFER_SIZE];
|
||||
int rv;
|
||||
|
||||
LOG_FUNC_CALLED(card->ctx);
|
||||
|
||||
/* Select application (deselect previously selected application) */
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0x04, 0x00);
|
||||
apdu.lc = aid->len;
|
||||
|
@ -354,7 +370,7 @@ iasecc_select_aid(struct sc_card *card, struct sc_aid *aid, unsigned char *out,
|
|||
LOG_TEST_RET(card->ctx, SC_ERROR_BUFFER_TOO_SMALL, "Cannot select AID");
|
||||
memcpy(out, apdu.resp, apdu.resplen);
|
||||
|
||||
return SC_SUCCESS;
|
||||
LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
@ -405,6 +421,11 @@ static int iasecc_parse_ef_atr(struct sc_card *card)
|
|||
sizes->recv = card->ef_atr->issuer_data[10] * 0x100 + card->ef_atr->issuer_data[11];
|
||||
sizes->recv_sc = card->ef_atr->issuer_data[14] * 0x100 + card->ef_atr->issuer_data[15];
|
||||
|
||||
sc_log(ctx,
|
||||
"EF.ATR: IO Buffer Size send/sc %"SC_FORMAT_LEN_SIZE_T"d/%"SC_FORMAT_LEN_SIZE_T"d "
|
||||
"recv/sc %"SC_FORMAT_LEN_SIZE_T"d/%"SC_FORMAT_LEN_SIZE_T"d",
|
||||
sizes->send, sizes->send_sc, sizes->recv, sizes->recv_sc);
|
||||
|
||||
card->max_send_size = sizes->send;
|
||||
card->max_recv_size = sizes->recv;
|
||||
|
||||
|
@ -591,6 +612,45 @@ iasecc_init_amos_or_sagem(struct sc_card *card)
|
|||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
}
|
||||
|
||||
inline static int
|
||||
iasecc_is_cpx(const struct sc_card *card)
|
||||
{
|
||||
switch(card->type) {
|
||||
case SC_CARD_TYPE_IASECC_CPX:
|
||||
case SC_CARD_TYPE_IASECC_CPXCL:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
iasecc_init_cpx(struct sc_card *card)
|
||||
{
|
||||
struct sc_context *ctx = card->ctx;
|
||||
unsigned int flags;
|
||||
int rv = 0;
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
|
||||
card->caps = IASECC_CARD_DEFAULT_CAPS;
|
||||
|
||||
flags = IASECC_CARD_DEFAULT_FLAGS;
|
||||
|
||||
_sc_card_add_rsa_alg(card, 512, flags, 0);
|
||||
_sc_card_add_rsa_alg(card, 1024, flags, 0);
|
||||
_sc_card_add_rsa_alg(card, 2048, flags, 0);
|
||||
|
||||
rv = iasecc_parse_ef_atr(card);
|
||||
if (rv)
|
||||
sc_invalidate_cache(card); /* avoid memory leakage */
|
||||
LOG_TEST_RET(ctx, rv, "Parse EF.ATR");
|
||||
|
||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
iasecc_init(struct sc_card *card)
|
||||
|
@ -618,6 +678,8 @@ iasecc_init(struct sc_card *card)
|
|||
rv = iasecc_init_amos_or_sagem(card);
|
||||
else if (card->type == SC_CARD_TYPE_IASECC_MI)
|
||||
rv = iasecc_init_amos_or_sagem(card);
|
||||
else if (iasecc_is_cpx(card))
|
||||
rv = iasecc_init_cpx(card);
|
||||
else {
|
||||
LOG_TEST_GOTO_ERR(ctx, SC_ERROR_INVALID_CARD, "");
|
||||
}
|
||||
|
@ -857,9 +919,11 @@ iasecc_select_file(struct sc_card *card, const struct sc_path *path,
|
|||
sc_log(ctx, "iasecc_select_file() path:%s", sc_print_path(path));
|
||||
|
||||
sc_print_cache(card);
|
||||
if (path->type != SC_PATH_TYPE_DF_NAME
|
||||
if ((!iasecc_is_cpx(card)) &&
|
||||
(card->type != SC_CARD_TYPE_IASECC_GEMALTO) &&
|
||||
(path->type != SC_PATH_TYPE_DF_NAME
|
||||
&& lpath.len >= 2
|
||||
&& lpath.value[0] == 0x3F && lpath.value[1] == 0x00) {
|
||||
&& lpath.value[0] == 0x3F && lpath.value[1] == 0x00)) {
|
||||
sc_log(ctx, "EF.ATR(aid:'%s')", card->ef_atr ? sc_dump_hex(card->ef_atr->aid.value, card->ef_atr->aid.len) : "");
|
||||
|
||||
rv = iasecc_select_mf(card, file_out);
|
||||
|
@ -940,7 +1004,8 @@ iasecc_select_file(struct sc_card *card, const struct sc_path *path,
|
|||
&& card->type != SC_CARD_TYPE_IASECC_SAGEM
|
||||
&& card->type != SC_CARD_TYPE_IASECC_AMOS
|
||||
&& card->type != SC_CARD_TYPE_IASECC_MI
|
||||
&& card->type != SC_CARD_TYPE_IASECC_MI2) {
|
||||
&& card->type != SC_CARD_TYPE_IASECC_MI2
|
||||
&& !iasecc_is_cpx(card)) {
|
||||
rv = SC_ERROR_NOT_SUPPORTED;
|
||||
LOG_TEST_GOTO_ERR(ctx, rv, "Unsupported card");
|
||||
}
|
||||
|
@ -952,7 +1017,10 @@ iasecc_select_file(struct sc_card *card, const struct sc_path *path,
|
|||
if (card->type == SC_CARD_TYPE_IASECC_OBERTHUR ||
|
||||
card->type == SC_CARD_TYPE_IASECC_AMOS ||
|
||||
card->type == SC_CARD_TYPE_IASECC_MI ||
|
||||
card->type == SC_CARD_TYPE_IASECC_MI2) {
|
||||
card->type == SC_CARD_TYPE_IASECC_MI2 ||
|
||||
card->type == SC_CARD_TYPE_IASECC_GEMALTO ||
|
||||
iasecc_is_cpx(card)
|
||||
) {
|
||||
apdu.p2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
@ -961,7 +1029,9 @@ iasecc_select_file(struct sc_card *card, const struct sc_path *path,
|
|||
if (card->type == SC_CARD_TYPE_IASECC_OBERTHUR ||
|
||||
card->type == SC_CARD_TYPE_IASECC_AMOS ||
|
||||
card->type == SC_CARD_TYPE_IASECC_MI ||
|
||||
card->type == SC_CARD_TYPE_IASECC_MI2) {
|
||||
card->type == SC_CARD_TYPE_IASECC_MI2 ||
|
||||
card->type == SC_CARD_TYPE_IASECC_GEMALTO ||
|
||||
iasecc_is_cpx(card)) {
|
||||
apdu.p2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
@ -974,7 +1044,9 @@ iasecc_select_file(struct sc_card *card, const struct sc_path *path,
|
|||
apdu.p1 = 0x04;
|
||||
if (card->type == SC_CARD_TYPE_IASECC_AMOS ||
|
||||
card->type == SC_CARD_TYPE_IASECC_MI2 ||
|
||||
card->type == SC_CARD_TYPE_IASECC_OBERTHUR) {
|
||||
card->type == SC_CARD_TYPE_IASECC_OBERTHUR ||
|
||||
card->type == SC_CARD_TYPE_IASECC_GEMALTO ||
|
||||
iasecc_is_cpx(card)) {
|
||||
apdu.p2 = 0x04;
|
||||
}
|
||||
}
|
||||
|
@ -998,6 +1070,7 @@ iasecc_select_file(struct sc_card *card, const struct sc_path *path,
|
|||
rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
if (rv == SC_ERROR_INCORRECT_PARAMETERS &&
|
||||
lpath.type == SC_PATH_TYPE_DF_NAME && apdu.p2 == 0x00) {
|
||||
sc_log(ctx, "Warning: SC_ERROR_INCORRECT_PARAMETERS for SC_PATH_TYPE_DF_NAME, try again with P2=0x0C");
|
||||
apdu.p2 = 0x0C;
|
||||
continue;
|
||||
}
|
||||
|
@ -1069,25 +1142,23 @@ iasecc_select_file(struct sc_card *card, const struct sc_path *path,
|
|||
|
||||
sc_log(ctx, "FileType %i", file->type);
|
||||
if (file->type == SC_FILE_TYPE_DF) {
|
||||
if (card->cache.valid)
|
||||
if (card->cache.valid) {
|
||||
sc_file_free(card->cache.current_df);
|
||||
}
|
||||
card->cache.current_df = NULL;
|
||||
|
||||
|
||||
if (card->cache.valid)
|
||||
sc_file_free(card->cache.current_ef);
|
||||
card->cache.current_ef = NULL;
|
||||
|
||||
sc_file_dup(&card->cache.current_df, file);
|
||||
card->cache.valid = 1;
|
||||
}
|
||||
else {
|
||||
if (card->cache.valid)
|
||||
if (card->cache.valid) {
|
||||
sc_file_free(card->cache.current_ef);
|
||||
}
|
||||
|
||||
card->cache.current_ef = NULL;
|
||||
|
||||
sc_file_dup(&card->cache.current_ef, file);
|
||||
card->cache.valid = 1;
|
||||
}
|
||||
|
||||
if (file_out) {
|
||||
|
@ -1125,8 +1196,8 @@ iasecc_process_fci(struct sc_card *card, struct sc_file *file,
|
|||
const unsigned char *buf, size_t buflen)
|
||||
{
|
||||
struct sc_context *ctx = card->ctx;
|
||||
size_t taglen;
|
||||
int rv, ii, offs;
|
||||
size_t taglen, offs, ii;
|
||||
int rv;
|
||||
const unsigned char *acls = NULL, *tag = NULL;
|
||||
unsigned char mask;
|
||||
unsigned char ops_DF[7] = {
|
||||
|
@ -1182,10 +1253,15 @@ iasecc_process_fci(struct sc_card *card, struct sc_file *file,
|
|||
for (ii = 0; ii < 7; ii++, mask /= 2) {
|
||||
unsigned char op = file->type == SC_FILE_TYPE_DF ? ops_DF[ii] : ops_EF[ii];
|
||||
|
||||
/* avoid any access to acls[offs] beyond the taglen */
|
||||
if (offs >= taglen) {
|
||||
sc_log(ctx, "Warning: Invalid offset reached during ACL parsing");
|
||||
break;
|
||||
}
|
||||
if (!(mask & acls[0]))
|
||||
continue;
|
||||
|
||||
sc_log(ctx, "ACLs mask 0x%X, offs %i, op 0x%X, acls[offs] 0x%X", mask, offs, op, acls[offs]);
|
||||
sc_log(ctx, "ACLs mask 0x%X, offs %"SC_FORMAT_LEN_SIZE_T"u, op 0x%X, acls[offs] 0x%X", mask, offs, op, acls[offs]);
|
||||
if (op == 0xFF) {
|
||||
;
|
||||
}
|
||||
|
@ -1493,8 +1569,9 @@ iasecc_delete_file(struct sc_card *card, const struct sc_path *path)
|
|||
rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
LOG_TEST_RET(ctx, rv, "Delete file failed");
|
||||
|
||||
if (card->cache.valid)
|
||||
if (card->cache.valid) {
|
||||
sc_file_free(card->cache.current_ef);
|
||||
}
|
||||
card->cache.current_ef = NULL;
|
||||
}
|
||||
|
||||
|
@ -1641,6 +1718,11 @@ iasecc_se_get_info(struct sc_card *card, struct iasecc_se_info *se)
|
|||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
|
||||
if (iasecc_is_cpx(card)) {
|
||||
rv = iasecc_select_mf(card, NULL);
|
||||
LOG_TEST_RET(ctx, rv, "MF invalid");
|
||||
}
|
||||
|
||||
if (se->reference > IASECC_SE_REF_MAX)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
|
||||
|
||||
|
@ -2797,6 +2879,34 @@ iasecc_sdo_get_tagged_data(struct sc_card *card, int sdo_tag, struct iasecc_sdo
|
|||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
|
||||
sc_log(ctx, "sdo_tag=0x%x sdo_ref=0x%x sdo_class=0x%x", sdo_tag,
|
||||
sdo->sdo_ref, sdo->sdo_class);
|
||||
|
||||
/* XXX: for the CPx, the SDO are available from some specific path */
|
||||
if (iasecc_is_cpx(card)) {
|
||||
struct sc_path path;
|
||||
char *path_str = NULL;
|
||||
switch(sdo_tag) {
|
||||
case IASECC_SDO_PRVKEY_TAG:
|
||||
/* APDU 00 CB 3F FF 0B 4D 09 70 07 BF 90 02 03 7F 48 80 */
|
||||
path_str = "3F00:0001";
|
||||
break;
|
||||
case IASECC_SDO_CHV_TAG:
|
||||
/* APDU 00 CB 3F FF 0B 4D 09 70 07 BF 81 01 03 7F 41 80 */
|
||||
path_str = "3F00";
|
||||
break;
|
||||
default:
|
||||
path_str = NULL;
|
||||
break;
|
||||
}
|
||||
if (path_str) {
|
||||
sc_log(ctx, "Warning: Enforce the path=%s", path_str);
|
||||
sc_format_path(path_str, &path);
|
||||
rv = iasecc_select_file(card, &path, NULL);
|
||||
LOG_TEST_RET(ctx, rv, "path error");
|
||||
}
|
||||
}
|
||||
|
||||
sbuf[offs--] = 0x80;
|
||||
sbuf[offs--] = sdo_tag & 0xFF;
|
||||
if ((sdo_tag >> 8) & 0xFF)
|
||||
|
|
|
@ -195,16 +195,25 @@ static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv,
|
|||
if (((memcmp(&start[4], "ksc", 3) == 0) || memcmp(&start[4], "kxc", 3) == 0)
|
||||
&& (memcmp(&start[12], "mscp", 5) == 0)) {
|
||||
new_object.fd++;
|
||||
if (card->type == SC_CARD_TYPE_IDPRIME_V2) {
|
||||
/* The key reference starts from 0x11 and increments by the key id (ASCII) */
|
||||
if (card->type == SC_CARD_TYPE_IDPRIME_V1) {
|
||||
/* The key reference is one bigger than the value found here for some reason */
|
||||
new_object.key_reference = start[8] + 1;
|
||||
} else {
|
||||
int key_id = 0;
|
||||
if (start[8] >= '0' && start[8] <= '9') {
|
||||
key_id = start[8] - '0';
|
||||
}
|
||||
new_object.key_reference = 0x11 + key_id;
|
||||
} else {
|
||||
/* The key reference is one bigger than the value found here for some reason */
|
||||
new_object.key_reference = start[8] + 1;
|
||||
switch (card->type) {
|
||||
case SC_CARD_TYPE_IDPRIME_V2:
|
||||
new_object.key_reference = 0x11 + key_id;
|
||||
break;
|
||||
case SC_CARD_TYPE_IDPRIME_V3:
|
||||
new_object.key_reference = 0xF7 + key_id;
|
||||
break;
|
||||
case SC_CARD_TYPE_IDPRIME_V4:
|
||||
new_object.key_reference = 0x56 + key_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found certificate with fd=%d, key_ref=%d",
|
||||
new_object.fd, new_object.key_reference);
|
||||
|
@ -252,6 +261,14 @@ static int idprime_init(sc_card_t *card)
|
|||
card->type = SC_CARD_TYPE_IDPRIME_V2;
|
||||
sc_log(card->ctx, "Detected IDPrime applet version 2");
|
||||
break;
|
||||
case 0x03:
|
||||
card->type = SC_CARD_TYPE_IDPRIME_V3;
|
||||
sc_log(card->ctx, "Detected IDPrime applet version 3");
|
||||
break;
|
||||
case 0x04:
|
||||
card->type = SC_CARD_TYPE_IDPRIME_V4;
|
||||
sc_log(card->ctx, "Detected IDPrime applet version 4");
|
||||
break;
|
||||
default:
|
||||
sc_log(card->ctx, "Unknown OS version received: %d", rbuf[11]);
|
||||
break;
|
||||
|
@ -290,6 +307,12 @@ static int idprime_init(sc_card_t *card)
|
|||
case SC_CARD_TYPE_IDPRIME_V2:
|
||||
card->name = "Gemalto IDPrime (OSv2)";
|
||||
break;
|
||||
case SC_CARD_TYPE_IDPRIME_V3:
|
||||
card->name = "Gemalto IDPrime (OSv3)";
|
||||
break;
|
||||
case SC_CARD_TYPE_IDPRIME_V4:
|
||||
card->name = "Gemalto IDPrime (OSv4)";
|
||||
break;
|
||||
case SC_CARD_TYPE_IDPRIME_GENERIC:
|
||||
default:
|
||||
card->name = "Gemalto IDPrime (generic)";
|
||||
|
@ -418,6 +441,7 @@ static int idprime_get_token_name(sc_card_t* card, char** tname)
|
|||
sc_path_t tinfo_path = {"\x00\x00", 2, 0, 0, SC_PATH_TYPE_PATH, {"", 0}};
|
||||
sc_file_t *file = NULL;
|
||||
u8 buf[2];
|
||||
char *name;
|
||||
int r;
|
||||
|
||||
LOG_FUNC_CALLED(card->ctx);
|
||||
|
@ -445,20 +469,22 @@ static int idprime_get_token_name(sc_card_t* card, char** tname)
|
|||
}
|
||||
sc_file_free(file);
|
||||
|
||||
*tname = malloc(buf[1]);
|
||||
if (*tname == NULL) {
|
||||
name = malloc(buf[1]);
|
||||
if (name == NULL) {
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
r = iso_ops->read_binary(card, 2, (unsigned char *)*tname, buf[1], 0);
|
||||
r = iso_ops->read_binary(card, 2, (unsigned char *)name, buf[1], 0);
|
||||
if (r < 1) {
|
||||
free(*tname);
|
||||
free(name);
|
||||
LOG_FUNC_RETURN(card->ctx, r);
|
||||
}
|
||||
|
||||
if ((*tname)[r-1] != '\0') {
|
||||
(*tname)[r-1] = '\0';
|
||||
if (name[r-1] != '\0') {
|
||||
name[r-1] = '\0';
|
||||
}
|
||||
*tname = name;
|
||||
|
||||
LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -615,13 +641,13 @@ idprime_set_security_env(struct sc_card *card,
|
|||
switch (env->operation) {
|
||||
case SC_SEC_OPERATION_DECIPHER:
|
||||
if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_OAEP) {
|
||||
if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA1) {
|
||||
if (env->algorithm_flags & SC_ALGORITHM_MGF1_SHA1) {
|
||||
new_env.algorithm_ref = 0x1D;
|
||||
} else if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA256) {
|
||||
} else if (env->algorithm_flags & SC_ALGORITHM_MGF1_SHA256) {
|
||||
new_env.algorithm_ref = 0x4D;
|
||||
} else if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA384) {
|
||||
} else if (env->algorithm_flags & SC_ALGORITHM_MGF1_SHA384) {
|
||||
new_env.algorithm_ref = 0x5D;
|
||||
} else if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA512) {
|
||||
} else if (env->algorithm_flags & SC_ALGORITHM_MGF1_SHA512) {
|
||||
new_env.algorithm_ref = 0x6D;
|
||||
}
|
||||
} else { /* RSA-PKCS without hashing */
|
||||
|
@ -630,11 +656,11 @@ idprime_set_security_env(struct sc_card *card,
|
|||
break;
|
||||
case SC_SEC_OPERATION_SIGN:
|
||||
if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PSS) {
|
||||
if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA256) {
|
||||
if (env->algorithm_flags & SC_ALGORITHM_MGF1_SHA256) {
|
||||
new_env.algorithm_ref = 0x45;
|
||||
} else if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA384) {
|
||||
} else if (env->algorithm_flags & SC_ALGORITHM_MGF1_SHA384) {
|
||||
new_env.algorithm_ref = 0x55;
|
||||
} else if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA512) {
|
||||
} else if (env->algorithm_flags & SC_ALGORITHM_MGF1_SHA512) {
|
||||
new_env.algorithm_ref = 0x65;
|
||||
}
|
||||
} else { /* RSA-PKCS */
|
||||
|
|
|
@ -503,6 +503,7 @@ static int itacns_get_serialnr(sc_card_t *card, sc_serial_number_t *serial)
|
|||
return SC_ERROR_WRONG_CARD;
|
||||
}
|
||||
len = file->size;
|
||||
sc_file_free(file);
|
||||
|
||||
//Returned file->size should be 16.
|
||||
//We choose to not consider it as critical, because some cards
|
||||
|
|
|
@ -882,6 +882,11 @@ select_file_by_fid(sc_card_t * card, unsigned short *pathptr,
|
|||
priv->curpathlen--;
|
||||
priv->is_ef = 0;
|
||||
}
|
||||
/* Free the previously allocated file so we do not leak memory here */
|
||||
if (file) {
|
||||
sc_file_free(*file);
|
||||
*file = NULL;
|
||||
}
|
||||
r = select_down(card, pathptr, 1, 0, file);
|
||||
}
|
||||
|
||||
|
|
|
@ -187,7 +187,7 @@ static int encode_file_structure(sc_card_t *card, const sc_file_t *file,
|
|||
*p++ = file->record_length;
|
||||
else
|
||||
*p++ = 0;
|
||||
if (file->status & SC_FILE_STATUS_INVALIDATED)
|
||||
if (file->status == SC_FILE_STATUS_INVALIDATED)
|
||||
*p++ = 0;
|
||||
else
|
||||
*p++ = 0x01;
|
||||
|
|
|
@ -43,9 +43,6 @@
|
|||
#define LOAD_KEY_EC_PRIVATE 0x1087
|
||||
#define LOAD_KEY_SYMMETRIC 0x20a0
|
||||
|
||||
#define MYEID_STATE_CREATION 0x01
|
||||
#define MYEID_STATE_ACTIVATED 0x07
|
||||
|
||||
#define MYEID_CARD_NAME_MAX_LEN 100
|
||||
|
||||
/* The following flags define the features supported by the card currently in use.
|
||||
|
@ -86,6 +83,7 @@ typedef struct myeid_private_data {
|
|||
ECDH key agreement. Note that this pointer is usually not valid
|
||||
after this pair of calls and must not be used elsewhere. */
|
||||
const struct sc_security_env* sec_env;
|
||||
int disable_hw_pkcs1_padding;
|
||||
} myeid_private_data_t;
|
||||
|
||||
typedef struct myeid_card_caps {
|
||||
|
@ -166,6 +164,34 @@ myeid_select_aid(struct sc_card *card, struct sc_aid *aid, unsigned char *out, s
|
|||
return SC_SUCCESS;
|
||||
}
|
||||
|
||||
static int myeid_load_options(sc_context_t *ctx, myeid_private_data_t *priv)
|
||||
{
|
||||
int r;
|
||||
size_t i, j;
|
||||
scconf_block **found_blocks, *block;
|
||||
|
||||
if (!ctx || !priv) {
|
||||
r = SC_ERROR_INTERNAL;
|
||||
goto err;
|
||||
}
|
||||
priv->disable_hw_pkcs1_padding = 0;
|
||||
for (i = 0; ctx->conf_blocks[i]; i++) {
|
||||
found_blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i],
|
||||
"card_driver", "myeid");
|
||||
if (!found_blocks)
|
||||
continue;
|
||||
for (j = 0, block = found_blocks[j]; block; j++, block = found_blocks[j]) {
|
||||
priv->disable_hw_pkcs1_padding = scconf_get_int(block, "disable_hw_pkcs1_padding", 0);
|
||||
sc_log(ctx,"Found config option: disable_hw_pkcs1_padding = %d\n", priv->disable_hw_pkcs1_padding);
|
||||
}
|
||||
free(found_blocks);
|
||||
}
|
||||
r = SC_SUCCESS;
|
||||
|
||||
err:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int myeid_init(struct sc_card *card)
|
||||
{
|
||||
unsigned long flags = 0, ext_flags = 0;
|
||||
|
@ -196,6 +222,9 @@ static int myeid_init(struct sc_card *card)
|
|||
if (!priv)
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = myeid_load_options (card->ctx, priv);
|
||||
LOG_TEST_GOTO_ERR(card->ctx, rv, "Unable to read options from opensc.conf");
|
||||
|
||||
priv->card_state = SC_FILE_STATUS_CREATION;
|
||||
card->drv_data = priv;
|
||||
|
||||
|
@ -224,8 +253,10 @@ static int myeid_init(struct sc_card *card)
|
|||
}
|
||||
}
|
||||
|
||||
flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_ONBOARD_KEY_GEN;
|
||||
flags |= SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_RSA_HASH_SHA1;
|
||||
flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_ONBOARD_KEY_GEN;
|
||||
if (priv->disable_hw_pkcs1_padding == 0)
|
||||
flags |= SC_ALGORITHM_RSA_PAD_PKCS1;
|
||||
flags |= SC_ALGORITHM_RSA_HASH_NONE;
|
||||
|
||||
_sc_card_add_rsa_alg(card, 512, flags, 0);
|
||||
_sc_card_add_rsa_alg(card, 768, flags, 0);
|
||||
|
@ -245,7 +276,7 @@ static int myeid_init(struct sc_card *card)
|
|||
int i;
|
||||
|
||||
flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ONBOARD_KEY_GEN;
|
||||
flags |= SC_ALGORITHM_ECDSA_HASH_NONE | SC_ALGORITHM_ECDSA_HASH_SHA1;
|
||||
flags |= SC_ALGORITHM_ECDSA_HASH_NONE;
|
||||
ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES;
|
||||
|
||||
for (i=0; ec_curves[i].curve_name != NULL; i++) {
|
||||
|
@ -441,20 +472,18 @@ static int myeid_process_fci(struct sc_card *card, struct sc_file *file,
|
|||
sc_log(card->ctx, "id (%X) sec_attr (%X %X %X)", file->id,
|
||||
file->sec_attr[0],file->sec_attr[1],file->sec_attr[2]);
|
||||
}
|
||||
tag = sc_asn1_find_tag(NULL, buf, buflen, 0x8A, &taglen);
|
||||
if (tag != NULL && taglen > 0)
|
||||
{
|
||||
if(tag[0] == MYEID_STATE_CREATION) {
|
||||
file->status = SC_FILE_STATUS_CREATION;
|
||||
sc_log(card->ctx, "File id (%X) status SC_FILE_STATUS_CREATION (0x%X)",
|
||||
file->id, tag[0]);
|
||||
}
|
||||
else if(tag[0] == MYEID_STATE_ACTIVATED) {
|
||||
file->status = SC_FILE_STATUS_ACTIVATED;
|
||||
sc_log(card->ctx, "File id (%X) status SC_FILE_STATUS_ACTIVATED (0x%X)",
|
||||
file->id, tag[0]);
|
||||
}
|
||||
priv->card_state = file->status;
|
||||
|
||||
priv->card_state = file->status;
|
||||
switch (file->status) {
|
||||
case SC_FILE_STATUS_CREATION:
|
||||
file->acl_inactive = 1;
|
||||
sc_log(card->ctx, "File id (%X) status SC_FILE_STATUS_CREATION", file->id);
|
||||
break;
|
||||
case SC_FILE_STATUS_ACTIVATED:
|
||||
sc_log(card->ctx, "File id (%X) status SC_FILE_STATUS_ACTIVATED", file->id);
|
||||
break;
|
||||
default:
|
||||
sc_log(card->ctx, "File id (%X) unusual status (0x%X)", file->id, file->status);
|
||||
}
|
||||
|
||||
LOG_FUNC_RETURN(card->ctx, 0);
|
||||
|
|
|
@ -539,7 +539,7 @@ auth_select_file(struct sc_card *card, const struct sc_path *in_path,
|
|||
}
|
||||
}
|
||||
|
||||
if (path.len - offs > 0) {
|
||||
if (path.len > offs) {
|
||||
struct sc_path tmp_path;
|
||||
|
||||
memset(&tmp_path, 0, sizeof(struct sc_path));
|
||||
|
@ -2206,6 +2206,9 @@ auth_read_record(struct sc_card *card, unsigned int nr_rec,
|
|||
"auth_read_record(): nr_rec %i; count %"SC_FORMAT_LEN_SIZE_T"u",
|
||||
nr_rec, count);
|
||||
|
||||
if (nr_rec > 0xFF)
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
|
||||
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB2, nr_rec, 0);
|
||||
apdu.p2 = (flags & SC_RECORD_EF_ID_MASK) << 3;
|
||||
if (flags & SC_RECORD_BY_REC_NR)
|
||||
|
|
|
@ -87,7 +87,11 @@ static struct sc_card_driver pgp_drv = {
|
|||
};
|
||||
|
||||
|
||||
static pgp_ec_curves_t ec_curves[] = {
|
||||
static pgp_ec_curves_t ec_curves_openpgp34[] = {
|
||||
/* OpenPGP 3.4+ Ed25519 and Curve25519 */
|
||||
{{{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, 256}, /* curve25519 for encryption => CKK_EC_MONTGOMERY */
|
||||
{{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, 256}, /* ed25519 for signatures => CKK_EC_EDWARDS */
|
||||
/* v3.0+ supports: [RFC 4880 & 6637] 0x12 = ECDH, 0x13 = ECDSA */
|
||||
{{{1, 2, 840, 10045, 3, 1, 7, -1}}, 256}, /* ansiX9p256r1 */
|
||||
{{{1, 3, 132, 0, 34, -1}}, 384}, /* ansiX9p384r1 */
|
||||
{{{1, 3, 132, 0, 35, -1}}, 521}, /* ansiX9p521r1 */
|
||||
|
@ -97,11 +101,16 @@ static pgp_ec_curves_t ec_curves[] = {
|
|||
{{{-1}}, 0} /* This entry must not be touched. */
|
||||
};
|
||||
|
||||
static pgp_ec_curves_t *ec_curves_openpgp = ec_curves_openpgp34 + 2;
|
||||
|
||||
struct sc_object_id curve25519_oid = {{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}};
|
||||
|
||||
/* Gnuk supports NIST, SECG and Curve25519 since version 1.2 */
|
||||
static pgp_ec_curves_t ec_curves_gnuk[] = {
|
||||
{{{1, 2, 840, 10045, 3, 1, 7, -1}}, 256}, /* ansiX9p256r1 */
|
||||
{{{1, 3, 132, 0, 10, -1}}, 256}, /* secp256k1 */
|
||||
/*{{{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, 256}, //cv25519
|
||||
{{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, 256}, // ed25519 */
|
||||
{{{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}}, 256}, /* curve25519 for encryption => CKK_EC_MONTGOMERY */
|
||||
{{{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}}, 256}, /* ed25519 for signatures => CKK_EC_EDWARDS */
|
||||
{{{-1}}, 0} /* This entry must not be touched. */
|
||||
};
|
||||
|
||||
|
@ -448,6 +457,15 @@ pgp_init(sc_card_t *card)
|
|||
: (priv->bcd_version < OPENPGP_CARD_3_4) ? pgp33_objects
|
||||
: pgp34_objects;
|
||||
|
||||
/* With gnuk, we use different curves */
|
||||
if (card->type == SC_CARD_TYPE_OPENPGP_GNUK) {
|
||||
priv->ec_curves = ec_curves_gnuk;
|
||||
} else if (priv->bcd_version >= OPENPGP_CARD_3_4) {
|
||||
priv->ec_curves = ec_curves_openpgp34;
|
||||
} else {
|
||||
priv->ec_curves = ec_curves_openpgp;
|
||||
}
|
||||
|
||||
/* change file path to MF for re-use in MF */
|
||||
sc_format_path("3f00", &file->path);
|
||||
|
||||
|
@ -500,22 +518,15 @@ pgp_init(sc_card_t *card)
|
|||
switch (card->type) {
|
||||
case SC_CARD_TYPE_OPENPGP_V3:
|
||||
/* RSA 1024 was removed for v3+ */
|
||||
_sc_card_add_rsa_alg(card, 2048, flags_rsa, 0);
|
||||
_sc_card_add_rsa_alg(card, 3072, flags_rsa, 0);
|
||||
_sc_card_add_rsa_alg(card, 4096, flags_rsa, 0);
|
||||
/* v3.0+ supports: [RFC 4880 & 6637] 0x12 = ECDH, 0x13 = ECDSA */
|
||||
for (i=0; ec_curves[i].oid.value[0] >= 0; i++)
|
||||
{
|
||||
_sc_card_add_ec_alg(card, ec_curves[i].size, flags_ecc, ext_flags, &ec_curves[i].oid);
|
||||
}
|
||||
break;
|
||||
_sc_card_add_rsa_alg(card, 3072, flags_rsa, 0);
|
||||
/* fallthrough */
|
||||
case SC_CARD_TYPE_OPENPGP_GNUK:
|
||||
_sc_card_add_rsa_alg(card, 2048, flags_rsa, 0);
|
||||
/* Gnuk supports NIST, SECG and Curve25519 since version 1.2 */
|
||||
for (i=0; ec_curves_gnuk[i].oid.value[0] >= 0; i++)
|
||||
for (i=0; priv->ec_curves[i].oid.value[0] >= 0; i++)
|
||||
{
|
||||
_sc_card_add_ec_alg(card, ec_curves_gnuk[i].size,
|
||||
flags_ecc, ext_flags, &ec_curves_gnuk[i].oid);
|
||||
_sc_card_add_ec_alg(card, priv->ec_curves[i].size,
|
||||
flags_ecc, ext_flags, &priv->ec_curves[i].oid);
|
||||
}
|
||||
break;
|
||||
case SC_CARD_TYPE_OPENPGP_V2:
|
||||
|
@ -565,21 +576,27 @@ pgp_parse_hist_bytes(sc_card_t *card, u8 *ctlv, size_t ctlv_len)
|
|||
* Internal: parse an algorithm attributes DO
|
||||
**/
|
||||
static int
|
||||
pgp_parse_algo_attr_blob(const pgp_blob_t *blob, sc_cardctl_openpgp_keygen_info_t *key_info)
|
||||
pgp_parse_algo_attr_blob(sc_card_t *card, const pgp_blob_t *blob,
|
||||
sc_cardctl_openpgp_keygen_info_t *key_info)
|
||||
{
|
||||
struct pgp_priv_data *priv = DRVDATA(card);
|
||||
struct sc_object_id oid;
|
||||
unsigned int j, r;
|
||||
|
||||
LOG_FUNC_CALLED(card->ctx);
|
||||
|
||||
if (blob == NULL || blob->data == NULL || blob->len == 0 ||
|
||||
blob->id < 0x00c1 || blob->id > 0x00c3 || key_info == NULL)
|
||||
return SC_ERROR_INCORRECT_PARAMETERS;
|
||||
blob->id < 0x00c1 || blob->id > 0x00c3 || key_info == NULL) {
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_INCORRECT_PARAMETERS);
|
||||
}
|
||||
|
||||
key_info->key_id = blob->id - 0x00c0; /* attribute algorithm blobs are C1 - C3 */
|
||||
|
||||
switch (blob->data[0]) {
|
||||
case SC_OPENPGP_KEYALGO_RSA:
|
||||
if (blob->len < 5)
|
||||
return SC_ERROR_INCORRECT_PARAMETERS;
|
||||
if (blob->len < 5) {
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_INCORRECT_PARAMETERS);
|
||||
}
|
||||
|
||||
key_info->algorithm = SC_OPENPGP_KEYALGO_RSA;
|
||||
key_info->u.rsa.modulus_len = bebytes2ushort(blob->data + 1);
|
||||
|
@ -591,11 +608,12 @@ pgp_parse_algo_attr_blob(const pgp_blob_t *blob, sc_cardctl_openpgp_keygen_info_
|
|||
break;
|
||||
case SC_OPENPGP_KEYALGO_ECDH:
|
||||
case SC_OPENPGP_KEYALGO_ECDSA:
|
||||
case SC_OPENPGP_KEYALGO_EDDSA:
|
||||
|
||||
/* SC_OPENPGP_KEYALGO_ECDH || SC_OPENPGP_KEYALGO_ECDSA */
|
||||
/* SC_OPENPGP_KEYALGO_ECDH || SC_OPENPGP_KEYALGO_ECDSA || SC_OPENPGP_KEYALGO_EDDSA */
|
||||
key_info->algorithm = blob->data[0];
|
||||
|
||||
/* last byte is only set if pubkey import is supported, empty otherwise*/
|
||||
/* last byte is set to 0xFF if pubkey import is supported */
|
||||
if (blob->data[blob->len-1] == SC_OPENPGP_KEYFORMAT_EC_STDPUB){
|
||||
if (blob->len < 3)
|
||||
return SC_ERROR_INCORRECT_PARAMETERS;
|
||||
|
@ -603,9 +621,14 @@ pgp_parse_algo_attr_blob(const pgp_blob_t *blob, sc_cardctl_openpgp_keygen_info_
|
|||
key_info->u.ec.keyformat = SC_OPENPGP_KEYFORMAT_EC_STDPUB;
|
||||
}
|
||||
else {
|
||||
/* otherwise, last byte could be 00, so let's ignore it, as
|
||||
* it is not part of OID */
|
||||
if (blob->len < 2)
|
||||
return SC_ERROR_INCORRECT_PARAMETERS;
|
||||
key_info->u.ec.oid_len = blob->len - 1;
|
||||
if (blob->data[blob->len-1] == SC_OPENPGP_KEYFORMAT_EC_STD)
|
||||
key_info->u.ec.oid_len = blob->len - 2;
|
||||
else
|
||||
key_info->u.ec.oid_len = blob->len - 1;
|
||||
key_info->u.ec.keyformat = SC_OPENPGP_KEYFORMAT_EC_STD;
|
||||
}
|
||||
|
||||
|
@ -618,20 +641,25 @@ pgp_parse_algo_attr_blob(const pgp_blob_t *blob, sc_cardctl_openpgp_keygen_info_
|
|||
return r;
|
||||
}
|
||||
/* compare with list of supported ec_curves */
|
||||
for (j=0; ec_curves[j].oid.value[0] >= 0; j++){
|
||||
if (sc_compare_oid(&ec_curves[j].oid, &oid)){
|
||||
key_info->u.ec.oid = ec_curves[j].oid;
|
||||
key_info->u.ec.key_length = ec_curves[j].size;
|
||||
for (j = 0; priv->ec_curves[j].oid.value[0] >= 0; j++) {
|
||||
if (sc_compare_oid(&priv->ec_curves[j].oid, &oid)) {
|
||||
sc_log(card->ctx, "Matched EC oid %s (%d)",
|
||||
sc_dump_oid(&oid), j);
|
||||
key_info->u.ec.oid = priv->ec_curves[j].oid;
|
||||
key_info->u.ec.key_length = priv->ec_curves[j].size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* We did not match the OID */
|
||||
if (priv->ec_curves[j].oid.value[0] < 0) {
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return SC_ERROR_NOT_IMPLEMENTED;
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
return SC_SUCCESS;
|
||||
LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
@ -647,6 +675,8 @@ pgp_get_card_features(sc_card_t *card)
|
|||
size_t i;
|
||||
pgp_blob_t *blob, *blob6e, *blob73;
|
||||
|
||||
LOG_FUNC_CALLED(card->ctx);
|
||||
|
||||
/* parse card capabilities from historical bytes in ATR */
|
||||
if (hist_bytes_len > 0) {
|
||||
/* category indicator 0x00, 0x10 or 0x80 => compact TLV (ISO) */
|
||||
|
@ -776,24 +806,46 @@ pgp_get_card_features(sc_card_t *card)
|
|||
for (i = 0x00c1; i <= 0x00c3; i++) {
|
||||
sc_cardctl_openpgp_keygen_info_t key_info;
|
||||
|
||||
sc_log(card->ctx, "Parsing algorithm attribues DO %zX" , i);
|
||||
|
||||
/* OpenPGP card spec 1.1 & 2.x section 4.3.3.6 / v3.x section 4.4.3.7 */
|
||||
if ((pgp_get_blob(card, blob73, i, &blob) >= 0) &&
|
||||
(pgp_parse_algo_attr_blob(blob, &key_info) >= 0)) {
|
||||
(pgp_parse_algo_attr_blob(card, blob, &key_info) >= 0)) {
|
||||
unsigned long flags = 0, ext_flags = 0;
|
||||
|
||||
/* RSA [RFC 4880] */
|
||||
if (key_info.algorithm == SC_OPENPGP_KEYALGO_RSA){
|
||||
switch (key_info.algorithm) {
|
||||
case SC_OPENPGP_KEYALGO_RSA:
|
||||
/* OpenPGP card spec 1.1 & 2.x, section 7.2.9 & 7.2.10 /
|
||||
* v3.x section 7.2.11 & 7.2.12 */
|
||||
unsigned long flags = SC_ALGORITHM_RSA_PAD_PKCS1 |
|
||||
SC_ALGORITHM_RSA_HASH_NONE |
|
||||
SC_ALGORITHM_ONBOARD_KEY_GEN; /* key gen on card */
|
||||
_sc_card_add_rsa_alg(card, key_info.u.rsa.modulus_len, flags, 0);
|
||||
}
|
||||
/* v3.0+: ECC [RFC 4880 & 6637] */
|
||||
else if (key_info.algorithm == SC_OPENPGP_KEYALGO_ECDH
|
||||
|| key_info.algorithm == SC_OPENPGP_KEYALGO_ECDSA) {
|
||||
flags = SC_ALGORITHM_RSA_PAD_PKCS1 |
|
||||
SC_ALGORITHM_RSA_HASH_NONE |
|
||||
SC_ALGORITHM_ONBOARD_KEY_GEN; /* key gen on card */
|
||||
|
||||
unsigned long flags, ext_flags;
|
||||
_sc_card_add_rsa_alg(card, key_info.u.rsa.modulus_len, flags, 0);
|
||||
sc_log(card->ctx, "DO %zX: Added RSA algorithm, mod_len = %"
|
||||
SC_FORMAT_LEN_SIZE_T"u",
|
||||
i, key_info.u.rsa.modulus_len);
|
||||
break;
|
||||
case SC_OPENPGP_KEYALGO_ECDH:
|
||||
/* The montgomery curve (curve25519) needs to go through
|
||||
* different paths, otherwise we handle it as a normal EC key */
|
||||
if (sc_compare_oid(&key_info.u.ec.oid, &curve25519_oid)) {
|
||||
/* CKM_XEDDSA supports both Sign and Derive, but
|
||||
* OpenPGP card supports only derivation using these
|
||||
* keys as far as I know */
|
||||
_sc_card_add_xeddsa_alg(card, key_info.u.ec.key_length,
|
||||
SC_ALGORITHM_ECDH_CDH_RAW, 0, &key_info.u.ec.oid);
|
||||
|
||||
sc_log(card->ctx, "DO %zX: Added XEDDSA algorithm (%d), mod_len = %d" ,
|
||||
i, key_info.algorithm, key_info.u.ec.key_length);
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
case SC_OPENPGP_KEYALGO_ECDSA:
|
||||
/* v3.0+: ECC [RFC 4880 & 6637] */
|
||||
/* EdDSA from draft-ietf-openpgp-rfc4880bis-08 */
|
||||
flags = 0, ext_flags = 0;
|
||||
|
||||
if (key_info.algorithm == SC_OPENPGP_KEYALGO_ECDH)
|
||||
flags = SC_ALGORITHM_ECDH_CDH_RAW;
|
||||
|
@ -804,7 +856,21 @@ pgp_get_card_features(sc_card_t *card)
|
|||
ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE;
|
||||
|
||||
_sc_card_add_ec_alg(card, key_info.u.ec.key_length, flags, ext_flags,
|
||||
&key_info.u.ec.oid);
|
||||
&key_info.u.ec.oid);
|
||||
sc_log(card->ctx, "DO %zX: Added EC algorithm (%d), mod_len = %d" ,
|
||||
i, key_info.algorithm, key_info.u.ec.key_length);
|
||||
break;
|
||||
case SC_OPENPGP_KEYALGO_EDDSA:
|
||||
_sc_card_add_eddsa_alg(card, key_info.u.ec.key_length,
|
||||
SC_ALGORITHM_EDDSA_RAW, 0, &key_info.u.ec.oid);
|
||||
|
||||
sc_log(card->ctx, "DO %zX: Added EDDSA algorithm (%d), mod_len = %d" ,
|
||||
i, key_info.algorithm, key_info.u.ec.key_length);
|
||||
break;
|
||||
default:
|
||||
sc_log(card->ctx, "DO %zX: Unknown algorithm ID (%d)" ,
|
||||
i, key_info.algorithm);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1551,10 +1617,6 @@ pgp_get_pubkey_pem(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len)
|
|||
else if ((r = pgp_get_blob(card, blob, 0x0086, &pubkey_blob)) >= 0
|
||||
&& (r = pgp_read_blob(card, pubkey_blob)) >= 0) {
|
||||
|
||||
p15pubkey.algorithm = SC_ALGORITHM_EC;
|
||||
p15pubkey.u.ec.ecpointQ.value = pubkey_blob->data;
|
||||
p15pubkey.u.ec.ecpointQ.len = pubkey_blob->len;
|
||||
|
||||
switch(tag & 0xFFFE) {
|
||||
case DO_SIGN: aa_tag = 0x00C1; break;
|
||||
case DO_ENCR: aa_tag = 0x00C2; break;
|
||||
|
@ -1567,31 +1629,73 @@ pgp_get_pubkey_pem(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len)
|
|||
if (aa_tag && ((r = pgp_get_blob(card, priv->mf, 0x006e, &blob6e)) >= 0) &&
|
||||
((r = pgp_get_blob(card, blob6e, 0x0073, &blob73)) >= 0) &&
|
||||
((r = pgp_get_blob(card, blob73, aa_tag, &aa_blob)) >= 0) &&
|
||||
((r = pgp_parse_algo_attr_blob(aa_blob, &key_info)) >= 0)) {
|
||||
|
||||
if ((r = sc_encode_oid(card->ctx, &key_info.u.ec.oid,
|
||||
&p15pubkey.u.ec.params.der.value,
|
||||
&p15pubkey.u.ec.params.der.len)) == 0) {
|
||||
p15pubkey.u.ec.params.type = 1;
|
||||
((r = pgp_parse_algo_attr_blob(card, aa_blob, &key_info)) >= 0)) {
|
||||
switch (key_info.algorithm) {
|
||||
case SC_OPENPGP_KEYALGO_EDDSA:
|
||||
/* In EDDSA key case we do not have to care about OIDs
|
||||
* as we support only one for now */
|
||||
p15pubkey.algorithm = SC_ALGORITHM_EDDSA;
|
||||
p15pubkey.u.eddsa.pubkey.value = pubkey_blob->data;
|
||||
p15pubkey.u.eddsa.pubkey.len = pubkey_blob->len;
|
||||
/* PKCS#11 3.0: 2.3.5 Edwards EC public keys only support the use
|
||||
* of the curveName selection to specify a curve name as defined
|
||||
* in [RFC 8032] */
|
||||
r = sc_pkcs15_encode_pubkey_as_spki(card->ctx, &p15pubkey, &data, &len);
|
||||
break;
|
||||
case SC_OPENPGP_KEYALGO_ECDH:
|
||||
/* This yields either EC(DSA) key or EC_MONTGOMERY (curve25519) key */
|
||||
if (sc_compare_oid(&key_info.u.ec.oid, &curve25519_oid)) {
|
||||
p15pubkey.algorithm = SC_ALGORITHM_XEDDSA;
|
||||
p15pubkey.u.eddsa.pubkey.value = pubkey_blob->data;
|
||||
p15pubkey.u.eddsa.pubkey.len = pubkey_blob->len;
|
||||
/* PKCS#11 3.0 2.3.7 Montgomery EC public keys only support
|
||||
* the use of the curveName selection to specify a curve
|
||||
* name as defined in [RFC7748] */
|
||||
/* XXX only curve25519 supported now. Theoretically could be
|
||||
* also curve448 or OIDs */
|
||||
|
||||
r = sc_pkcs15_encode_pubkey_as_spki(card->ctx, &p15pubkey, &data, &len);
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
case SC_OPENPGP_KEYALGO_ECDSA:
|
||||
if ((r = sc_encode_oid(card->ctx, &key_info.u.ec.oid,
|
||||
&p15pubkey.u.ec.params.der.value,
|
||||
&p15pubkey.u.ec.params.der.len)) == 0) {
|
||||
p15pubkey.algorithm = SC_ALGORITHM_EC;
|
||||
p15pubkey.u.ec.ecpointQ.value = pubkey_blob->data;
|
||||
p15pubkey.u.ec.ecpointQ.len = pubkey_blob->len;
|
||||
p15pubkey.u.ec.params.type = 1;
|
||||
r = sc_pkcs15_encode_pubkey_as_spki(card->ctx, &p15pubkey, &data, &len);
|
||||
} else {
|
||||
sc_log(card->ctx, "Unable to encode EC curve OID from algorithm info");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sc_log(card->ctx, "Unknown algorithm ID received (%d)", key_info.algorithm);
|
||||
break;
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
sc_log(card->ctx, "Unable to find Algorithm Attribute for EC curve OID");
|
||||
}
|
||||
else
|
||||
}
|
||||
} else {
|
||||
LOG_TEST_RET(card->ctx, r, "error getting elements");
|
||||
}
|
||||
|
||||
/* clean up anything we may have set in p15pubkey that can not be freed */
|
||||
if (p15pubkey.algorithm == SC_ALGORITHM_RSA) {
|
||||
if (p15pubkey.algorithm == SC_ALGORITHM_RSA) {
|
||||
p15pubkey.u.rsa.modulus.data = NULL;
|
||||
p15pubkey.u.rsa.modulus.len = 0;
|
||||
p15pubkey.u.rsa.exponent.data = NULL;
|
||||
p15pubkey.u.rsa.exponent.len = 0;
|
||||
} else
|
||||
if (p15pubkey.algorithm == SC_ALGORITHM_EC) {
|
||||
} else if (p15pubkey.algorithm == SC_ALGORITHM_EC) {
|
||||
p15pubkey.u.ec.ecpointQ.value = NULL;
|
||||
p15pubkey.u.ec.ecpointQ.len = 0;
|
||||
/* p15pubkey.u.ec.params.der and named_curve will be freed by sc_pkcs15_erase_pubkey */
|
||||
} else if (p15pubkey.algorithm == SC_ALGORITHM_EDDSA
|
||||
|| p15pubkey.algorithm == SC_ALGORITHM_XEDDSA) {
|
||||
p15pubkey.u.eddsa.pubkey.value = NULL;
|
||||
p15pubkey.u.eddsa.pubkey.len = 0;
|
||||
}
|
||||
sc_pkcs15_erase_pubkey(&p15pubkey);
|
||||
|
||||
|
@ -1769,9 +1873,8 @@ pgp_put_data(sc_card_t *card, unsigned int tag, const u8 *buf, size_t buf_len)
|
|||
|
||||
LOG_FUNC_CALLED(card->ctx);
|
||||
|
||||
/* check if the tag is writable */
|
||||
if (priv->current->id != tag)
|
||||
affected_blob = pgp_find_blob(card, tag);
|
||||
/* Check if there is a blob for the given tag */
|
||||
affected_blob = pgp_find_blob(card, tag);
|
||||
|
||||
/* Non-readable DOs have no represented blob, we have to check from pgp_get_info_by_tag */
|
||||
if (affected_blob == NULL)
|
||||
|
@ -1779,6 +1882,7 @@ pgp_put_data(sc_card_t *card, unsigned int tag, const u8 *buf, size_t buf_len)
|
|||
else
|
||||
dinfo = affected_blob->info;
|
||||
|
||||
/* Make sure the DO exists and is writeable */
|
||||
if (dinfo == NULL) {
|
||||
sc_log(card->ctx, "The DO %04X does not exist.", tag);
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
|
||||
|
@ -1843,7 +1947,7 @@ pgp_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left)
|
|||
|
||||
/* In general, the PIN Reference is extracted from the key-id,
|
||||
* for example, CHV0 -> Ref=0, CHV1 -> Ref=1.
|
||||
* However, in the case of OpenGPG, the PIN Ref to compose APDU
|
||||
* However, in the case of OpenPGP, the PIN Ref to compose APDU
|
||||
* must be 81, 82, 83.
|
||||
* So, if we receive Ref=1, Ref=2, we must convert to 81, 82...
|
||||
* In OpenPGP v1, the PINs are named CHV1, CHV2, CHV3.
|
||||
|
@ -1964,6 +2068,7 @@ int pgp_logout(struct sc_card *card)
|
|||
|
||||
/**
|
||||
* ABI: ISO 7816-8 SET SECURITY ENVIRONMENT.
|
||||
* This is optional in the OpenPGP Card 3.4 specs
|
||||
*/
|
||||
static int
|
||||
pgp_set_security_env(sc_card_t *card,
|
||||
|
@ -1973,9 +2078,11 @@ pgp_set_security_env(sc_card_t *card,
|
|||
|
||||
LOG_FUNC_CALLED(card->ctx);
|
||||
|
||||
/* The SC_SEC_ENV_ALG_PRESENT is set always so let it pass for GNUK */
|
||||
if ((env->flags & SC_SEC_ENV_ALG_PRESENT)
|
||||
&& (env->algorithm != SC_ALGORITHM_RSA)
|
||||
&& (priv->bcd_version < OPENPGP_CARD_3_0))
|
||||
&& (priv->bcd_version < OPENPGP_CARD_3_0)
|
||||
&& (card->type != SC_CARD_TYPE_OPENPGP_GNUK))
|
||||
LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS,
|
||||
"only RSA algorithm supported");
|
||||
|
||||
|
@ -2006,6 +2113,9 @@ pgp_set_security_env(sc_card_t *card,
|
|||
"requested usage");
|
||||
}
|
||||
break;
|
||||
case SC_SEC_OPERATION_DERIVE:
|
||||
sc_log(card->ctx, "Operation: Derive: No particular action needed");
|
||||
break;
|
||||
default:
|
||||
LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS,
|
||||
"invalid operation");
|
||||
|
@ -2093,6 +2203,9 @@ pgp_compute_signature(sc_card_t *card, const u8 *data,
|
|||
break;
|
||||
case 0x01:
|
||||
default:
|
||||
/* From PKCS #11 point of view, we should be able to use
|
||||
* curve25519 to do digital signature, but it is not how it
|
||||
* is used in OpenPGP so we will not allow it here */
|
||||
LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS,
|
||||
"invalid key reference");
|
||||
}
|
||||
|
@ -2129,21 +2242,86 @@ pgp_decipher(sc_card_t *card, const u8 *in, size_t inlen,
|
|||
sc_security_env_t *env = &priv->sec_env;
|
||||
sc_apdu_t apdu;
|
||||
u8 apdu_case = SC_APDU_CASE_4;
|
||||
u8 *temp = NULL;
|
||||
u8 *temp = NULL, *p = NULL;
|
||||
size_t templen, pklen, dolen;
|
||||
int r;
|
||||
|
||||
LOG_FUNC_CALLED(card->ctx);
|
||||
|
||||
/* padding according to OpenPGP card spec 1.1 & 2.x section 7.2.9 / 3.x section 7.2.11 */
|
||||
if (!(temp = malloc(inlen + 1)))
|
||||
/* padding according to OpenPGP card spec 1.1 & 2.x section 7.2.9 / 3.x section 7.2.11
|
||||
* The longest possible prefix is 10 bytes for ECDH */
|
||||
templen = inlen + 10;
|
||||
if (!(temp = malloc(templen)))
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
|
||||
/* padding byte: 0xa6 = ECC; 0x00 = RSA; 0x02 = AES */
|
||||
(env->algorithm == SC_ALGORITHM_EC) ? (temp[0] = 0xa6) : (temp[0] = 0x00);
|
||||
memcpy(temp + 1, in, inlen);
|
||||
in = temp;
|
||||
inlen += 1;
|
||||
|
||||
if (env->operation != SC_SEC_OPERATION_DECIPHER) {
|
||||
/* padding byte: 0xa6 = ECC; 0x00 = RSA; 0x02 = AES */
|
||||
switch (env->algorithm) {
|
||||
case SC_ALGORITHM_RSA:
|
||||
/* This is just PKCS#1.5 start byte and it should be already
|
||||
* provided by the padding routines. But it lets put it here
|
||||
* to make sure it does not conflict with following indicators */
|
||||
temp[0] = 0x00;
|
||||
memcpy(temp + 1, in, inlen);
|
||||
inlen += 1;
|
||||
break;
|
||||
|
||||
case SC_ALGORITHM_EC:
|
||||
case SC_ALGORITHM_XEDDSA:
|
||||
/* Calculate length of External Public Key (0x86) */
|
||||
r = sc_asn1_put_tag(0x86, NULL, inlen, NULL, 0, NULL);
|
||||
if (r <= 0) {
|
||||
free(temp);
|
||||
LOG_FUNC_RETURN(card->ctx, r);
|
||||
}
|
||||
pklen = r;
|
||||
|
||||
/* Calculate lenght of Public Key DO (0x7F49) */
|
||||
r = sc_asn1_put_tag(0x7f49, NULL, pklen, NULL, 0, NULL);
|
||||
if (r <= 0) {
|
||||
free(temp);
|
||||
LOG_FUNC_RETURN(card->ctx, r);
|
||||
}
|
||||
dolen = r;
|
||||
|
||||
p = temp;
|
||||
/* This is 0xA6 Cipher DO with associated length field */
|
||||
r = sc_asn1_put_tag(0xA6, NULL, dolen, p, templen - (p - temp), &p);
|
||||
if (r != SC_SUCCESS) {
|
||||
free(temp);
|
||||
LOG_FUNC_RETURN(card->ctx, r);
|
||||
}
|
||||
|
||||
/* Public Key DO (0x7F49) with associated length field */
|
||||
r = sc_asn1_put_tag(0x7F49, NULL, pklen, p, templen - (p - temp), &p);
|
||||
if (r != SC_SUCCESS) {
|
||||
free(temp);
|
||||
LOG_FUNC_RETURN(card->ctx, r);
|
||||
}
|
||||
|
||||
/* External Public Key (0x86) with associated length */
|
||||
r = sc_asn1_put_tag(0x86, in, inlen, p, templen - (p - temp), &p);
|
||||
if (r != SC_SUCCESS) {
|
||||
free(temp);
|
||||
LOG_FUNC_RETURN(card->ctx, r);
|
||||
}
|
||||
inlen = (p - temp);
|
||||
break;
|
||||
case SC_ALGORITHM_AES:
|
||||
/* not supported yet */
|
||||
/*
|
||||
temp[0] = 0x02;
|
||||
memcpy(temp + 1, in, inlen);
|
||||
inlen += 1;
|
||||
*/
|
||||
/* fall through */
|
||||
default:
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
|
||||
}
|
||||
|
||||
in = temp;
|
||||
|
||||
if (env->operation != SC_SEC_OPERATION_DECIPHER &&
|
||||
env->operation != SC_SEC_OPERATION_DERIVE) {
|
||||
free(temp);
|
||||
LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS,
|
||||
"invalid operation");
|
||||
|
@ -2223,7 +2401,8 @@ pgp_update_new_algo_attr(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_
|
|||
if (priv->ext_caps & EXT_CAP_ALG_ATTR_CHANGEABLE) {
|
||||
/* ECDSA and ECDH */
|
||||
if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH
|
||||
|| key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA){
|
||||
|| key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA
|
||||
|| key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA){
|
||||
data_len = key_info->u.ec.oid_len+1;
|
||||
data = malloc(data_len);
|
||||
if (!data)
|
||||
|
@ -2270,7 +2449,7 @@ pgp_update_new_algo_attr(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_
|
|||
} else {
|
||||
sc_cardctl_openpgp_keygen_info_t old_key_info;
|
||||
|
||||
if (pgp_parse_algo_attr_blob(algo_blob, &old_key_info) != SC_SUCCESS
|
||||
if (pgp_parse_algo_attr_blob(card, algo_blob, &old_key_info) != SC_SUCCESS
|
||||
|| old_key_info.algorithm != key_info->algorithm)
|
||||
LOG_TEST_RET(card->ctx, SC_ERROR_NO_CARD_SUPPORT,
|
||||
"Requested algorithm not supported");
|
||||
|
@ -2427,7 +2606,8 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime,
|
|||
}
|
||||
/* ECC */
|
||||
else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH
|
||||
|| key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA) {
|
||||
|| key_info->algorithm == SC_OPENPGP_KEYALGO_ECDSA
|
||||
|| key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA) {
|
||||
/* Algorithm ID, see https://tools.ietf.org/html/rfc6637#section-5 */
|
||||
*p = key_info->algorithm + 6;
|
||||
p += 1;
|
||||
|
@ -2721,6 +2901,9 @@ pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info)
|
|||
&& card->type < SC_CARD_TYPE_OPENPGP_V3
|
||||
&& card->type != SC_CARD_TYPE_OPENPGP_GNUK)
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
|
||||
if (key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA
|
||||
&& card->type != SC_CARD_TYPE_OPENPGP_GNUK)
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
|
||||
|
||||
/* set Control Reference Template for key */
|
||||
if (key_info->key_id == SC_OPENPGP_KEY_SIGN)
|
||||
|
|
|
@ -184,6 +184,8 @@ struct pgp_priv_data {
|
|||
size_t max_cert_size;
|
||||
size_t max_specialDO_size;
|
||||
|
||||
pgp_ec_curves_t *ec_curves;
|
||||
|
||||
sc_security_env_t sec_env;
|
||||
};
|
||||
|
||||
|
|
|
@ -305,6 +305,7 @@ struct piv_object {
|
|||
};
|
||||
|
||||
/* Must be in order, and one per enumerated PIV_OBJ */
|
||||
// clang-format off
|
||||
static const struct piv_object piv_objects[] = {
|
||||
{ PIV_OBJ_CCC, "Card Capability Container",
|
||||
"2.16.840.1.101.3.7.1.219.0", 3, "\x5F\xC1\x07", "\xDB\x00", 0},
|
||||
|
@ -455,6 +456,7 @@ static const struct piv_object piv_objects[] = {
|
|||
"2.16.840.1.101.3.7.2.9999.120", 2, "\x95\x06", "\x95\x06", PIV_OBJECT_TYPE_PUBKEY},
|
||||
{ PIV_OBJ_LAST_ENUM, "", "", 0, "", "", 0}
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
static struct sc_card_operations piv_ops;
|
||||
|
||||
|
@ -606,14 +608,12 @@ static int piv_generate_key(sc_card_t *card,
|
|||
const u8 *cp;
|
||||
keydata->exponent = 0;
|
||||
|
||||
/* expected tag is 7f49. */
|
||||
/* we will whatever tag is present */
|
||||
|
||||
cp = rbuf;
|
||||
in_len = r;
|
||||
|
||||
/* expected tag is 0x7f49,returned as cla_out == 0x60 and tag_out = 0x1F49 */
|
||||
r = sc_asn1_read_tag(&cp, in_len, &cla_out, &tag_out, &in_len);
|
||||
if (cp == NULL) {
|
||||
if (cp == NULL || in_len == 0 || cla_out != 0x60 || tag_out != 0x1f49) {
|
||||
r = SC_ERROR_ASN1_OBJECT_NOT_FOUND;
|
||||
}
|
||||
if (r != SC_SUCCESS) {
|
||||
|
@ -1030,7 +1030,7 @@ piv_cache_internal_data(sc_card_t *card, int enumtag)
|
|||
priv->obj_cache[enumtag].obj_len,
|
||||
0x53, &bodylen);
|
||||
|
||||
if (body == NULL)
|
||||
if (body == NULL || priv->obj_cache[enumtag].obj_data[0] != 0x53)
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_VALID);
|
||||
|
||||
/* get the certificate out */
|
||||
|
@ -1609,7 +1609,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card,
|
|||
/* Remove the encompassing outer TLV of 0x7C and get the data */
|
||||
body = sc_asn1_find_tag(card->ctx, rbuf,
|
||||
r, 0x7C, &body_len);
|
||||
if (!body) {
|
||||
if (!body || rbuf[0] != 0x7C) {
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid Witness Data response of NULL\n");
|
||||
r = SC_ERROR_INVALID_DATA;
|
||||
goto err;
|
||||
|
@ -1751,7 +1751,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card,
|
|||
/* Remove the encompassing outer TLV of 0x7C and get the data */
|
||||
body = sc_asn1_find_tag(card->ctx, rbuf,
|
||||
r, 0x7C, &body_len);
|
||||
if(!body) {
|
||||
if(!body || rbuf[0] != 0x7C) {
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not find outer tag 0x7C in response");
|
||||
r = SC_ERROR_INVALID_DATA;
|
||||
goto err;
|
||||
|
@ -1912,7 +1912,7 @@ static int piv_general_external_authenticate(sc_card_t *card,
|
|||
/* Remove the encompassing outer TLV of 0x7C and get the data */
|
||||
body = sc_asn1_find_tag(card->ctx, rbuf,
|
||||
r, 0x7C, &body_len);
|
||||
if (!body) {
|
||||
if (!body || rbuf[0] != 0x7C) {
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid Challenge Data response of NULL\n");
|
||||
r = SC_ERROR_INVALID_DATA;
|
||||
goto err;
|
||||
|
@ -2077,7 +2077,7 @@ piv_get_serial_nr_from_CHUI(sc_card_t* card, sc_serial_number_t* serial)
|
|||
r = SC_ERROR_INTERNAL;
|
||||
if (rbuflen != 0) {
|
||||
body = sc_asn1_find_tag(card->ctx, rbuf, rbuflen, 0x53, &bodylen); /* Pass the outer wrapper asn1 */
|
||||
if (body != NULL && bodylen != 0) {
|
||||
if (body != NULL && bodylen != 0 && rbuf[0] == 0x53) {
|
||||
fascn = sc_asn1_find_tag(card->ctx, body, bodylen, 0x30, &fascnlen); /* Find the FASC-N data */
|
||||
guid = sc_asn1_find_tag(card->ctx, body, bodylen, 0x34, &guidlen);
|
||||
|
||||
|
@ -2309,10 +2309,10 @@ static int piv_validate_general_authentication(sc_card_t *card,
|
|||
piv_private_data_t * priv = PIV_DATA(card);
|
||||
int r, tmplen, tmplen2;
|
||||
u8 *p;
|
||||
const u8 *tag;
|
||||
const unsigned char *p2;
|
||||
size_t taglen;
|
||||
const u8 *body;
|
||||
size_t bodylen;
|
||||
unsigned int cla, tag;
|
||||
unsigned int real_alg_id, op_tag;
|
||||
|
||||
u8 sbuf[4096]; /* needs work. for 3072 keys, needs 384+10 or so */
|
||||
|
@ -2365,20 +2365,28 @@ static int piv_validate_general_authentication(sc_card_t *card,
|
|||
|
||||
r = piv_general_io(card, 0x87, real_alg_id, priv->key_ref,
|
||||
sbuf, p - sbuf, rbuf, sizeof rbuf);
|
||||
if (r < 0)
|
||||
goto err;
|
||||
|
||||
if (r >= 0) {
|
||||
body = sc_asn1_find_tag(card->ctx, rbuf, r, 0x7c, &bodylen);
|
||||
if (body) {
|
||||
tag = sc_asn1_find_tag(card->ctx, body, bodylen, 0x82, &taglen);
|
||||
if (tag) {
|
||||
memcpy(out, tag, taglen);
|
||||
r = taglen;
|
||||
} else
|
||||
r = SC_ERROR_INVALID_DATA;
|
||||
} else
|
||||
r = SC_ERROR_INVALID_DATA;
|
||||
p2 = rbuf;
|
||||
r = sc_asn1_read_tag(&p2, r, &cla, &tag, &bodylen);
|
||||
if (p2 == NULL || r < 0 || bodylen == 0 || (cla|tag) != 0x7C) {
|
||||
LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find 0x7C");
|
||||
}
|
||||
|
||||
r = sc_asn1_read_tag(&p2, bodylen, &cla, &tag, &taglen);
|
||||
if (p2 == NULL || r < 0 || taglen == 0 || (cla|tag) != 0x82) {
|
||||
LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find 0x82");
|
||||
}
|
||||
|
||||
if (taglen > outlen) {
|
||||
LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "data read longer then buffer");
|
||||
}
|
||||
|
||||
memcpy(out, p2, taglen);
|
||||
r = taglen;
|
||||
|
||||
err:
|
||||
LOG_FUNC_RETURN(card->ctx, r);
|
||||
}
|
||||
|
||||
|
@ -2392,19 +2400,19 @@ piv_compute_signature(sc_card_t *card, const u8 * data, size_t datalen,
|
|||
int i;
|
||||
size_t nLen;
|
||||
u8 rbuf[128]; /* For EC conversions 384 will fit */
|
||||
const u8 * body;
|
||||
size_t bodylen;
|
||||
const u8 * tag;
|
||||
size_t taglen;
|
||||
const unsigned char *pseq, *pint, *ptemp, *pend;
|
||||
unsigned int cla, tag;
|
||||
size_t seqlen;
|
||||
size_t intlen;
|
||||
size_t templen;
|
||||
|
||||
SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
|
||||
|
||||
/* The PIV returns a DER SEQUENCE{INTEGER, INTEGER}
|
||||
* Which may have leading 00 to force positive
|
||||
* TODO: -DEE should check if PKCS15 want the same
|
||||
* But PKCS11 just wants 2* filed_length in bytes
|
||||
* Which may have leading 00 to force a positive integer
|
||||
* But PKCS11 just wants 2* field_length in bytes
|
||||
* So we have to strip out the integers
|
||||
* if present and pad on left if too short.
|
||||
* and pad on left if too short.
|
||||
*/
|
||||
|
||||
if (priv->alg_id == 0x11 || priv->alg_id == 0x14 ) {
|
||||
|
@ -2422,32 +2430,32 @@ piv_compute_signature(sc_card_t *card, const u8 * data, size_t datalen,
|
|||
if (r < 0)
|
||||
goto err;
|
||||
|
||||
body = sc_asn1_find_tag(card->ctx, rbuf, r, 0x30, &bodylen);
|
||||
pseq = rbuf;
|
||||
r = sc_asn1_read_tag(&pseq, r, &cla, &tag, &seqlen);
|
||||
if (pseq == NULL || r < 0 || seqlen == 0 || (cla|tag) != 0x30)
|
||||
LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find 0x30");
|
||||
|
||||
for (i = 0; i<2; i++) {
|
||||
if (body) {
|
||||
tag = sc_asn1_find_tag(card->ctx, body, bodylen, 0x02, &taglen);
|
||||
if (tag) {
|
||||
bodylen -= taglen - (tag - body);
|
||||
body = tag + taglen;
|
||||
pint = pseq;
|
||||
pend = pseq + seqlen;
|
||||
for (i = 0; i < 2; i++) {
|
||||
r = sc_asn1_read_tag(&pint, (pend - pint), &cla, &tag, &intlen);
|
||||
if (pint == NULL || r < 0 || intlen == 0 || (cla|tag) != 0x02)
|
||||
LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find 0x02");
|
||||
if (intlen > nLen + 1)
|
||||
LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA,"Signature too long");
|
||||
|
||||
if (taglen > nLen) { /* drop leading 00 if present */
|
||||
if (*tag != 0x00) {
|
||||
r = SC_ERROR_INVALID_DATA;
|
||||
goto err;
|
||||
}
|
||||
tag++;
|
||||
taglen--;
|
||||
}
|
||||
memcpy(out + nLen*i + nLen - taglen , tag, taglen);
|
||||
} else {
|
||||
r = SC_ERROR_INVALID_DATA;
|
||||
goto err;
|
||||
ptemp = pint;
|
||||
templen = intlen;
|
||||
if (intlen > nLen) { /* drop leading 00 if present */
|
||||
if (*ptemp != 0x00) {
|
||||
LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA,"Signature too long");
|
||||
}
|
||||
} else {
|
||||
r = SC_ERROR_INVALID_DATA;
|
||||
goto err;
|
||||
ptemp++;
|
||||
templen--;
|
||||
}
|
||||
memcpy(out + nLen*i + nLen - templen, ptemp, templen);
|
||||
pint += intlen; /* next integer */
|
||||
|
||||
}
|
||||
r = 2 * nLen;
|
||||
} else { /* RSA is all set */
|
||||
|
@ -2603,7 +2611,7 @@ static int piv_parse_discovery(sc_card_t *card, u8 * rbuf, size_t rbuflen, int a
|
|||
if (pinp && pinplen == 2) {
|
||||
sc_log(card->ctx, "Discovery pinp flags=0x%2.2x 0x%2.2x",*pinp, *(pinp+1));
|
||||
r = SC_SUCCESS;
|
||||
if (*pinp == 0x60 && *(pinp+1) == 0x20) { /* use Global pin */
|
||||
if ((*pinp & 0x60) == 0x60 && *(pinp+1) == 0x20) { /* use Global pin */
|
||||
sc_log(card->ctx, "Pin Preference - Global");
|
||||
priv->pin_preference = 0x00;
|
||||
}
|
||||
|
@ -2732,7 +2740,7 @@ static int piv_find_discovery(sc_card_t *card)
|
|||
|
||||
/*
|
||||
* During piv_match or piv_card_reader_lock_obtained,
|
||||
* we use the discovery object to test if card present, and
|
||||
* we use the discovery object to test if card present, and
|
||||
* if PIV AID is active. So we can not use the cache
|
||||
*/
|
||||
|
||||
|
@ -3039,8 +3047,8 @@ static int piv_match_card(sc_card_t *card)
|
|||
return 0; /* can not handle the card */
|
||||
}
|
||||
/* its one we know, or we can test for it in piv_init */
|
||||
/*
|
||||
* We will call piv_match_card_continued here then
|
||||
/*
|
||||
* We will call piv_match_card_continued here then
|
||||
* again in piv_init to avoid any issues with passing
|
||||
* anything from piv_match_card
|
||||
* to piv_init as had been done in the past
|
||||
|
@ -3187,7 +3195,7 @@ static int piv_match_card_continued(sc_card_t *card)
|
|||
* Try to avoid doing a select_aid and losing the login state on some cards.
|
||||
* We may get interference on some cards by other drivers trying SELECT_AID before
|
||||
* we get to see if PIV application is still active
|
||||
* putting PIV driver first might help.
|
||||
* putting PIV driver first might help.
|
||||
* This may fail if the wrong AID is active.
|
||||
* Discovery Object introduced in 800-73-3 so will return 0 if found and PIV applet active.
|
||||
* Will fail with SC_ERROR_FILE_NOT_FOUND if 800-73-3 and no Discovery object.
|
||||
|
@ -3264,10 +3272,10 @@ static int piv_match_card_continued(sc_card_t *card)
|
|||
sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d i:%d CI:%08x r:%d\n", card->type, i, priv->card_issues, r);
|
||||
if (i >= 0 && (priv->card_issues & CI_DISCOVERY_USELESS) == 0) {
|
||||
/*
|
||||
* We now know PIV AID is active, test DISCOVERY object again
|
||||
* Some PIV don't support DISCOVERY and return
|
||||
* SC_ERROR_INCORRECT_PARAMETERS. Any error
|
||||
* including SC_ERROR_FILE_NOT_FOUND means we cannot use discovery
|
||||
* We now know PIV AID is active, test DISCOVERY object again
|
||||
* Some PIV don't support DISCOVERY and return
|
||||
* SC_ERROR_INCORRECT_PARAMETERS. Any error
|
||||
* including SC_ERROR_FILE_NOT_FOUND means we cannot use discovery
|
||||
* to test for active AID.
|
||||
*/
|
||||
int i7e = piv_find_discovery(card);
|
||||
|
@ -3350,18 +3358,18 @@ static int piv_init(sc_card_t *card)
|
|||
}
|
||||
|
||||
/*
|
||||
* Set card_issues flags based card->type and version numbers if available.
|
||||
* Set card_issues flags based card->type and version numbers if available.
|
||||
*
|
||||
* YubiKey NEO, Yubikey 4 and other devices with PIV applets, have compliance
|
||||
* issues with the NIST 800-73-3 specs. The OpenSC developers do not have
|
||||
* access to all the different devices or versions of the devices.
|
||||
* Vendor and user input is welcome on any compliance issues.
|
||||
* access to all the different devices or versions of the devices.
|
||||
* Vendor and user input is welcome on any compliance issues.
|
||||
*
|
||||
* For the Yubico devices The assumption is also made that if a bug is
|
||||
* For the Yubico devices The assumption is also made that if a bug is
|
||||
* fixed in a Yubico version that means it is fixed on both NEO and Yubikey 4.
|
||||
*
|
||||
* The flags CI_CANT_USE_GETDATA_FOR_STATE and CI_DISCOVERY_USELESS
|
||||
* may be set earlier or later then in the following code.
|
||||
* may be set earlier or later then in the following code.
|
||||
*/
|
||||
|
||||
sc_debug(card->ctx,SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d CI:%08x r:%d\n", card->type, priv->card_issues, r);
|
||||
|
@ -3463,7 +3471,7 @@ static int piv_init(sc_card_t *card)
|
|||
* We want to process them now as this has information on what
|
||||
* keys and certs the card has and how the pin might be used.
|
||||
* If they fail, ignore it there are optional and introduced in
|
||||
* NIST 800-73-3 and NIST 800-73-2 so some older cards may
|
||||
* NIST 800-73-3 and NIST 800-73-2 so some older cards may
|
||||
* not handle the request.
|
||||
*/
|
||||
piv_process_history(card);
|
||||
|
@ -3626,7 +3634,7 @@ piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left)
|
|||
|
||||
/*
|
||||
* If called to check on the login state for a context specific login
|
||||
* return not logged in. Needed because of logic in e6f7373ef066
|
||||
* return not logged in. Needed because of logic in e6f7373ef066
|
||||
*/
|
||||
if (data->pin_type == SC_AC_CONTEXT_SPECIFIC) {
|
||||
data->pin1.logged_in = 0;
|
||||
|
@ -3648,9 +3656,9 @@ piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left)
|
|||
|
||||
/*
|
||||
* If this was for a CKU_CONTEXT_SPECFIC login, lock the card one more time.
|
||||
* to avoid any interference from other applications.
|
||||
* Sc_unlock will be called at a later time after the next card command
|
||||
* that should be a crypto operation. If its not then it is a error by the
|
||||
* to avoid any interference from other applications.
|
||||
* Sc_unlock will be called at a later time after the next card command
|
||||
* that should be a crypto operation. If its not then it is a error by the
|
||||
* calling application.
|
||||
*/
|
||||
if (data->cmd == SC_PIN_CMD_VERIFY && data->pin_type == SC_AC_CONTEXT_SPECIFIC) {
|
||||
|
|
|
@ -366,6 +366,19 @@ static int rtecp_logout(sc_card_t *card)
|
|||
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
|
||||
}
|
||||
|
||||
static int rtecp_set_security_env( struct sc_card *card,
|
||||
const struct sc_security_env *env,
|
||||
int se_num)
|
||||
{
|
||||
struct sc_security_env se_env;
|
||||
if(!env)
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
|
||||
se_env= *env;
|
||||
se_env.flags &= ~SC_SEC_ENV_FILE_REF_PRESENT;
|
||||
return iso_ops->set_security_env(card, &se_env, se_num);
|
||||
}
|
||||
|
||||
static int rtecp_cipher(sc_card_t *card, const u8 *data, size_t data_len,
|
||||
u8 *out, size_t out_len, int sign)
|
||||
{
|
||||
|
@ -824,7 +837,7 @@ struct sc_card_driver * sc_get_rtecp_driver(void)
|
|||
rtecp_ops.verify = rtecp_verify;
|
||||
rtecp_ops.logout = rtecp_logout;
|
||||
/* restore_security_env */
|
||||
/* set_security_env */
|
||||
rtecp_ops.set_security_env = rtecp_set_security_env;
|
||||
rtecp_ops.decipher = rtecp_decipher;
|
||||
rtecp_ops.compute_signature = rtecp_compute_signature;
|
||||
rtecp_ops.change_reference_data = rtecp_change_reference_data;
|
||||
|
|
|
@ -718,6 +718,7 @@ static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data,
|
|||
data->pin2.offset = 5;
|
||||
|
||||
r = (*iso_ops->pin_cmd)(card, data, tries_left);
|
||||
data->apdu = NULL;
|
||||
}
|
||||
LOG_TEST_RET(card->ctx, r, "Verification failed");
|
||||
|
||||
|
|
|
@ -654,16 +654,18 @@ static int tcos_decipher(sc_card_t *card, const u8 * crgram, size_t crgram_len,
|
|||
LOG_TEST_RET(ctx, r, "APDU transmit failed");
|
||||
|
||||
if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
|
||||
size_t len = (apdu.resplen>outlen) ? outlen : apdu.resplen;
|
||||
size_t len = (apdu.resplen > outlen) ? outlen : apdu.resplen;
|
||||
unsigned int offset = 0;
|
||||
|
||||
if (tcos3 && (data->pad_flags & SC_ALGORITHM_RSA_PAD_PKCS1) && apdu.resp[0] == 0 && apdu.resp[1] == 2) {
|
||||
if (tcos3 && (data->pad_flags & SC_ALGORITHM_RSA_PAD_PKCS1)
|
||||
&& len > 2 && apdu.resp[0] == 0 && apdu.resp[1] == 2) {
|
||||
offset = 2;
|
||||
while (offset < len && apdu.resp[offset] != 0)
|
||||
++offset;
|
||||
offset = (offset < len - 1) ? offset + 1 : 0;
|
||||
}
|
||||
memcpy(out, apdu.resp + offset, len-offset);
|
||||
if (offset < len)
|
||||
memcpy(out, apdu.resp + offset, len - offset);
|
||||
SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, len - offset);
|
||||
}
|
||||
SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2));
|
||||
|
|
|
@ -805,6 +805,7 @@ static int westcos_pin_cmd(sc_card_t * card, struct sc_pin_cmd_data *data,
|
|||
} else {
|
||||
r = SC_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
data->apdu = NULL;
|
||||
}
|
||||
if (r)
|
||||
return (r);
|
||||
|
|
|
@ -163,7 +163,7 @@ static void sc_card_free(sc_card_t *card)
|
|||
int i;
|
||||
for (i=0; i<card->algorithm_count; i++) {
|
||||
struct sc_algorithm_info *info = (card->algorithms + i);
|
||||
if (info->algorithm == SC_ALGORITHM_EC) {
|
||||
if (info->algorithm == SC_ALGORITHM_EC) {
|
||||
struct sc_ec_parameters ep = info->u._ec.params;
|
||||
|
||||
free(ep.named_curve);
|
||||
|
@ -1096,16 +1096,18 @@ int _sc_card_add_symmetric_alg(sc_card_t *card, unsigned int algorithm,
|
|||
return _sc_card_add_algorithm(card, &info);
|
||||
}
|
||||
|
||||
int _sc_card_add_ec_alg(sc_card_t *card, unsigned int key_length,
|
||||
static int
|
||||
_sc_card_add_ec_alg_int(sc_card_t *card, unsigned int key_length,
|
||||
unsigned long flags, unsigned long ext_flags,
|
||||
struct sc_object_id *curve_oid)
|
||||
struct sc_object_id *curve_oid,
|
||||
int algorithm)
|
||||
{
|
||||
sc_algorithm_info_t info;
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
sc_init_oid(&info.u._ec.params.id);
|
||||
|
||||
info.algorithm = SC_ALGORITHM_EC;
|
||||
info.algorithm = algorithm;
|
||||
info.key_length = key_length;
|
||||
info.flags = flags;
|
||||
|
||||
|
@ -1116,6 +1118,32 @@ int _sc_card_add_ec_alg(sc_card_t *card, unsigned int key_length,
|
|||
return _sc_card_add_algorithm(card, &info);
|
||||
}
|
||||
|
||||
int _sc_card_add_ec_alg(sc_card_t *card, unsigned int key_length,
|
||||
unsigned long flags, unsigned long ext_flags,
|
||||
struct sc_object_id *curve_oid)
|
||||
{
|
||||
return _sc_card_add_ec_alg_int(card, key_length, flags, ext_flags,
|
||||
curve_oid, SC_ALGORITHM_EC);
|
||||
}
|
||||
|
||||
int _sc_card_add_eddsa_alg(sc_card_t *card, unsigned int key_length,
|
||||
unsigned long flags, unsigned long ext_flags,
|
||||
struct sc_object_id *curve_oid)
|
||||
{
|
||||
/* For simplicity, share the ec union with the curve information */
|
||||
return _sc_card_add_ec_alg_int(card, key_length, flags, ext_flags,
|
||||
curve_oid, SC_ALGORITHM_EDDSA);
|
||||
}
|
||||
|
||||
int _sc_card_add_xeddsa_alg(sc_card_t *card, unsigned int key_length,
|
||||
unsigned long flags, unsigned long ext_flags,
|
||||
struct sc_object_id *curve_oid)
|
||||
{
|
||||
/* For simplicity, share the ec union with the curve information */
|
||||
return _sc_card_add_ec_alg_int(card, key_length, flags, ext_flags,
|
||||
curve_oid, SC_ALGORITHM_XEDDSA);
|
||||
}
|
||||
|
||||
sc_algorithm_info_t * sc_card_find_alg(sc_card_t *card,
|
||||
unsigned int algorithm, unsigned int key_length, void *param)
|
||||
{
|
||||
|
@ -1126,13 +1154,15 @@ sc_algorithm_info_t * sc_card_find_alg(sc_card_t *card,
|
|||
|
||||
if (info->algorithm != algorithm)
|
||||
continue;
|
||||
if (param) {
|
||||
if (info->algorithm == SC_ALGORITHM_EC ||
|
||||
info->algorithm == SC_ALGORITHM_EDDSA ||
|
||||
info->algorithm == SC_ALGORITHM_XEDDSA)
|
||||
if (sc_compare_oid((struct sc_object_id *)param, &info->u._ec.params.id))
|
||||
return info;
|
||||
}
|
||||
if (info->key_length != key_length)
|
||||
continue;
|
||||
if (param) {
|
||||
if (info->algorithm == SC_ALGORITHM_EC)
|
||||
if(!sc_compare_oid((struct sc_object_id *)param, &info->u._ec.params.id))
|
||||
continue;
|
||||
}
|
||||
return info;
|
||||
}
|
||||
return NULL;
|
||||
|
@ -1144,6 +1174,18 @@ sc_algorithm_info_t * sc_card_find_ec_alg(sc_card_t *card,
|
|||
return sc_card_find_alg(card, SC_ALGORITHM_EC, key_length, curve_name);
|
||||
}
|
||||
|
||||
sc_algorithm_info_t * sc_card_find_eddsa_alg(sc_card_t *card,
|
||||
unsigned int key_length, struct sc_object_id *curve_name)
|
||||
{
|
||||
return sc_card_find_alg(card, SC_ALGORITHM_EDDSA, key_length, curve_name);
|
||||
}
|
||||
|
||||
sc_algorithm_info_t * sc_card_find_xeddsa_alg(sc_card_t *card,
|
||||
unsigned int key_length, struct sc_object_id *curve_name)
|
||||
{
|
||||
return sc_card_find_alg(card, SC_ALGORITHM_XEDDSA, key_length, curve_name);
|
||||
}
|
||||
|
||||
int _sc_card_add_rsa_alg(sc_card_t *card, unsigned int key_length,
|
||||
unsigned long flags, unsigned long exponent)
|
||||
{
|
||||
|
@ -1367,6 +1409,8 @@ scconf_block *sc_get_conf_block(sc_context_t *ctx, const char *name1, const char
|
|||
void sc_invalidate_cache(struct sc_card *card)
|
||||
{
|
||||
if (card) {
|
||||
sc_file_free(card->cache.current_ef);
|
||||
sc_file_free(card->cache.current_df);
|
||||
memset(&card->cache, 0, sizeof(card->cache));
|
||||
card->cache.valid = 0;
|
||||
}
|
||||
|
|
|
@ -974,6 +974,7 @@ typedef struct sc_cardctl_piv_genkey_info_st {
|
|||
#define SC_OPENPGP_KEYALGO_RSA 0x01
|
||||
#define SC_OPENPGP_KEYALGO_ECDH 0x12
|
||||
#define SC_OPENPGP_KEYALGO_ECDSA 0x13
|
||||
#define SC_OPENPGP_KEYALGO_EDDSA 0x16
|
||||
|
||||
#define SC_OPENPGP_KEYFORMAT_RSA_STD 0 /* See 4.3.3.6 Algorithm Attributes */
|
||||
#define SC_OPENPGP_KEYFORMAT_RSA_STDN 1 /* OpenPGP card spec v2 */
|
||||
|
|
|
@ -205,6 +205,8 @@ enum {
|
|||
SC_CARD_TYPE_IASECC_AMOS,
|
||||
SC_CARD_TYPE_IASECC_MI,
|
||||
SC_CARD_TYPE_IASECC_MI2,
|
||||
SC_CARD_TYPE_IASECC_CPX,
|
||||
SC_CARD_TYPE_IASECC_CPXCL,
|
||||
|
||||
/* SmartCard-HSM */
|
||||
SC_CARD_TYPE_SC_HSM = 26000,
|
||||
|
@ -244,6 +246,7 @@ enum {
|
|||
SC_CARD_TYPE_CAC_GENERIC,
|
||||
SC_CARD_TYPE_CAC_I,
|
||||
SC_CARD_TYPE_CAC_II,
|
||||
SC_CARD_TYPE_CAC_ALT_HID,
|
||||
|
||||
/* nPA cards */
|
||||
SC_CARD_TYPE_NPA = 34000,
|
||||
|
@ -265,6 +268,8 @@ enum {
|
|||
SC_CARD_TYPE_IDPRIME_BASE = 37000,
|
||||
SC_CARD_TYPE_IDPRIME_V1,
|
||||
SC_CARD_TYPE_IDPRIME_V2,
|
||||
SC_CARD_TYPE_IDPRIME_V3,
|
||||
SC_CARD_TYPE_IDPRIME_V4,
|
||||
SC_CARD_TYPE_IDPRIME_GENERIC,
|
||||
|
||||
/* eDO cards */
|
||||
|
|
|
@ -1008,7 +1008,16 @@ int sc_get_cache_dir(sc_context_t *ctx, char *buf, size_t bufsize)
|
|||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
cache_dir = ".eid/cache";
|
||||
#ifdef __APPLE__
|
||||
cache_dir = getenv("Caches");
|
||||
#else
|
||||
cache_dir = getenv("XDG_CACHE_HOME");
|
||||
#endif
|
||||
if (cache_dir != NULL && cache_dir[0] != '\0') {
|
||||
snprintf(buf, bufsize, "%s/%s", cache_dir, "opensc");
|
||||
return SC_SUCCESS;
|
||||
}
|
||||
cache_dir = ".cache/opensc";
|
||||
homedir = getenv("HOME");
|
||||
#else
|
||||
cache_dir = "eid-cache";
|
||||
|
@ -1020,7 +1029,7 @@ int sc_get_cache_dir(sc_context_t *ctx, char *buf, size_t bufsize)
|
|||
homedir = temp_path;
|
||||
}
|
||||
#endif
|
||||
if (homedir == NULL)
|
||||
if (homedir == NULL || homedir[0] == '\0')
|
||||
return SC_ERROR_INTERNAL;
|
||||
if (snprintf(buf, bufsize, "%s/%s", homedir, cache_dir) < 0)
|
||||
return SC_ERROR_BUFFER_TOO_SMALL;
|
||||
|
|
|
@ -405,6 +405,7 @@ static u8 sn_ifd_pin_1[] = { 0xd0, 0x02, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x04 };
|
|||
#define AC_RAIZ_COMPONENTES_ISSUER "/C=ES/O=DIRECCION GENERAL DE LA POLICIA/OU=DNIE/OU=AC RAIZ COMPONENTES/CN=000000006573524449600006"
|
||||
#define AC_RAIZ_COMPONENTES_2_NEW_IDX 1
|
||||
#define AC_RAIZ_COMPONENTES_2_ISSUER "/C=ES/O=DIRECCION GENERAL DE LA POLICIA/OU=DNIE/organizationIdentifier=VATES-S2816015H/OU=AC RAIZ COMPONENTES 2/CN=000000006573524449620018"
|
||||
#define AC_RAIZ_COMPONENTES_2_ISSUER_OU "/OU=AC RAIZ COMPONENTES 2/"
|
||||
|
||||
/**
|
||||
* The DNIe secure channel uses some static configuration.
|
||||
|
@ -649,7 +650,7 @@ static int dnie_set_channel_data(sc_card_t * card, X509 * icc_intermediate_ca_ce
|
|||
sc_log(card->ctx, "icc_intermediate_ca_cert issuer %s", buf);
|
||||
}
|
||||
|
||||
if (buf && strcmp(buf, AC_RAIZ_COMPONENTES_2_ISSUER) == 0) {
|
||||
if (buf && strstr(buf, AC_RAIZ_COMPONENTES_2_ISSUER_OU)) {
|
||||
sc_log(card->ctx, "assigning new data channel configuration");
|
||||
priv_data->channel_data = &channel_data[AC_RAIZ_COMPONENTES_2_NEW_IDX];
|
||||
} else {
|
||||
|
|
|
@ -519,8 +519,8 @@ static int cwa_internal_auth(sc_card_t * card, u8 * sig, size_t sig_len, u8 * da
|
|||
* @return SC_SUCCESS if ok; else errorcode
|
||||
*/
|
||||
static int cwa_prepare_external_auth(sc_card_t * card,
|
||||
RSA * icc_pubkey,
|
||||
RSA * ifd_privkey,
|
||||
const RSA * icc_pubkey,
|
||||
const RSA * ifd_privkey,
|
||||
u8 * sig,
|
||||
size_t sig_len)
|
||||
{
|
||||
|
@ -594,7 +594,7 @@ static int cwa_prepare_external_auth(sc_card_t * card,
|
|||
buf3[127] = 0xBC; /* iso padding */
|
||||
|
||||
/* encrypt with ifd private key */
|
||||
len2 = RSA_private_decrypt(128, buf3, buf2, ifd_privkey, RSA_NO_PADDING);
|
||||
len2 = RSA_private_decrypt(128, buf3, buf2, (RSA *)ifd_privkey, RSA_NO_PADDING);
|
||||
if (len2 < 0) {
|
||||
msg = "Prepare external auth: ifd_privk encrypt failed";
|
||||
res = SC_ERROR_SM_ENCRYPT_FAILED;
|
||||
|
@ -630,7 +630,7 @@ static int cwa_prepare_external_auth(sc_card_t * card,
|
|||
}
|
||||
|
||||
/* re-encrypt result with icc public key */
|
||||
len1 = RSA_public_encrypt(len3, buf3, buf1, icc_pubkey, RSA_NO_PADDING);
|
||||
len1 = RSA_public_encrypt(len3, buf3, buf1, (RSA *)icc_pubkey, RSA_NO_PADDING);
|
||||
if (len1 <= 0 || (size_t) len1 != sig_len) {
|
||||
msg = "Prepare external auth: icc_pubk encrypt failed";
|
||||
res = SC_ERROR_SM_ENCRYPT_FAILED;
|
||||
|
@ -842,8 +842,8 @@ static int cwa_compare_signature(u8 * data, size_t dlen, u8 * ifd_data)
|
|||
* @return SC_SUCCESS if ok; else error code
|
||||
*/
|
||||
static int cwa_verify_internal_auth(sc_card_t * card,
|
||||
RSA * icc_pubkey,
|
||||
RSA * ifd_privkey,
|
||||
const RSA * icc_pubkey,
|
||||
const RSA * ifd_privkey,
|
||||
u8 * ifdbuf,
|
||||
size_t ifdlen,
|
||||
u8 * sig,
|
||||
|
@ -901,7 +901,7 @@ static int cwa_verify_internal_auth(sc_card_t * card,
|
|||
*/
|
||||
|
||||
/* decrypt data with our ifd priv key */
|
||||
len1 = RSA_private_decrypt(sig_len, sig, buf1, ifd_privkey, RSA_NO_PADDING);
|
||||
len1 = RSA_private_decrypt(sig_len, sig, buf1, (RSA *)ifd_privkey, RSA_NO_PADDING);
|
||||
if (len1 <= 0) {
|
||||
msg = "Verify Signature: decrypt with ifd privk failed";
|
||||
res = SC_ERROR_SM_ENCRYPT_FAILED;
|
||||
|
@ -911,7 +911,7 @@ static int cwa_verify_internal_auth(sc_card_t * card,
|
|||
/* OK: now we have SIGMIN in buf1 */
|
||||
/* check if SIGMIN data matches SIG or N.ICC-SIG */
|
||||
/* evaluate DS[SK.ICC.AUTH](SIG) trying to decrypt with icc pubk */
|
||||
len3 = RSA_public_encrypt(len1, buf1, buf3, icc_pubkey, RSA_NO_PADDING);
|
||||
len3 = RSA_public_encrypt(len1, buf1, buf3, (RSA *) icc_pubkey, RSA_NO_PADDING);
|
||||
if (len3 <= 0)
|
||||
goto verify_nicc_sig; /* evaluate N.ICC-SIG and retry */
|
||||
res = cwa_compare_signature(buf3, len3, ifdbuf);
|
||||
|
@ -945,7 +945,7 @@ static int cwa_verify_internal_auth(sc_card_t * card,
|
|||
}
|
||||
/* ok: check again with new data */
|
||||
/* evaluate DS[SK.ICC.AUTH](I.ICC-SIG) trying to decrypt with icc pubk */
|
||||
len3 = RSA_public_encrypt(len2, buf2, buf3, icc_pubkey, RSA_NO_PADDING);
|
||||
len3 = RSA_public_encrypt(len2, buf2, buf3, (RSA *)icc_pubkey, RSA_NO_PADDING);
|
||||
if (len3 <= 0) {
|
||||
msg = "Verify Signature: cannot get valid SIG data";
|
||||
res = SC_ERROR_INVALID_DATA;
|
||||
|
|
|
@ -39,7 +39,11 @@ static const struct app_entry apps[] = {
|
|||
{ (const u8 *) "\xA0\x00\x00\x00\x63PKCS-15", 12, "PKCS #15" },
|
||||
{ (const u8 *) "\xA0\x00\x00\x01\x77PKCS-15", 12, "Belgian eID" },
|
||||
{ (const u8 *) "\x44\x46\x20\x69\x73\x73\x75\x65\x72", 9, "Portugal eID" },
|
||||
{ (const u8 *) "\xE8\x28\xBD\x08\x0F\xA0\x00\x00\x01\x67\x45\x53\x49\x47\x4E", 15, "ESIGN"}
|
||||
{ (const u8 *) "\xE8\x28\xBD\x08\x0F\xA0\x00\x00\x01\x67\x45\x53\x49\x47\x4E", 15, "ESIGN"},
|
||||
{ (const u8 *) "\xE8\x28\xBD\x08\x0F\x80\x25\x00\x00\x01\xFF\x00\x10", 13, "CPx IAS"},
|
||||
{ (const u8 *) "\xE8\x28\xBD\x08\x0F\x80\x25\x00\x00\x01\xFF\x00\x20", 13, "CPx IAS CL"},
|
||||
{ (const u8 *) "\xE8\x28\xBD\x08\x0F\xD2\x50\x45\x43\x43\x2D\x65\x49\x44", 14, "ECC eID"},
|
||||
{ (const u8 *) "\xE8\x28\xBD\x08\x0F\xD2\x50\x47\x65\x6E\x65\x72\x69\x63", 14, "ECC Generic PKI"},
|
||||
};
|
||||
|
||||
static const struct sc_asn1_entry c_asn1_dirrecord[] = {
|
||||
|
|
|
@ -143,6 +143,7 @@ int sc_parse_ef_atr(struct sc_card *card)
|
|||
int rv;
|
||||
unsigned char *buf = NULL;
|
||||
size_t size;
|
||||
size_t off = 0;
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
|
||||
|
@ -162,8 +163,16 @@ int sc_parse_ef_atr(struct sc_card *card)
|
|||
}
|
||||
rv = sc_read_binary(card, 0, buf, size, 0);
|
||||
LOG_TEST_GOTO_ERR(ctx, rv, "Cannot read EF(ATR) file");
|
||||
|
||||
rv = sc_parse_ef_atr_content(card, buf, rv);
|
||||
|
||||
/* Workaround: Some cards seem to have a buggy storage of the EF.ATR */
|
||||
if ((card->type == SC_CARD_TYPE_IASECC_CPX) ||
|
||||
(card->type == SC_CARD_TYPE_IASECC_CPXCL)) {
|
||||
/* Let's keep the first byte */
|
||||
if ((rv > 1) &&
|
||||
(buf[0] == ISO7816_II_CATEGORY_TLV))
|
||||
off++;
|
||||
}
|
||||
rv = sc_parse_ef_atr_content(card, buf + off, rv - off);
|
||||
LOG_TEST_GOTO_ERR(ctx, rv, "EF(ATR) parse error");
|
||||
|
||||
rv = SC_SUCCESS;
|
||||
|
|
|
@ -133,4 +133,5 @@ struct iasecc_private_data {
|
|||
|
||||
struct iasecc_se_info *se_info;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -93,6 +93,7 @@ typedef unsigned __int8 uint8_t;
|
|||
#define SCARD_S_SUCCESS 0x00000000 /**< No error was encountered. */
|
||||
#define SCARD_E_CANCELLED 0x80100002 /**< The action was cancelled by an SCardCancel request. */
|
||||
#define SCARD_E_INVALID_HANDLE 0x80100003 /**< The supplied handle was invalid. */
|
||||
#define SCARD_E_UNKNOWN_READER 0x80100009 /**< The specified reader name is not recognized. */
|
||||
#define SCARD_E_TIMEOUT 0x8010000A /**< The user-specified timeout value has expired. */
|
||||
#define SCARD_E_SHARING_VIOLATION 0x8010000B /**< The smart card cannot be accessed because of other connections outstanding. */
|
||||
#define SCARD_E_NO_SMARTCARD 0x8010000C /**< The operation requires a smart card, but no smart card is currently in the device. */
|
||||
|
|
|
@ -153,6 +153,12 @@ int _sc_card_add_rsa_alg(struct sc_card *card, unsigned int key_length,
|
|||
int _sc_card_add_ec_alg(struct sc_card *card, unsigned int key_length,
|
||||
unsigned long flags, unsigned long ext_flags,
|
||||
struct sc_object_id *curve_oid);
|
||||
int _sc_card_add_eddsa_alg(struct sc_card *card, unsigned int key_length,
|
||||
unsigned long flags, unsigned long ext_flags,
|
||||
struct sc_object_id *curve_oid);
|
||||
int _sc_card_add_xeddsa_alg(struct sc_card *card, unsigned int key_length,
|
||||
unsigned long flags, unsigned long ext_flags,
|
||||
struct sc_object_id *curve_oid);
|
||||
|
||||
/********************************************************************/
|
||||
/* pkcs1 padding/encoding functions */
|
||||
|
|
|
@ -172,6 +172,9 @@ iso7816_read_record(struct sc_card *card,
|
|||
struct sc_apdu apdu;
|
||||
int r;
|
||||
|
||||
if (rec_nr > 0xFF)
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
|
||||
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0xB2, rec_nr, 0);
|
||||
apdu.le = count;
|
||||
apdu.resplen = count;
|
||||
|
@ -328,6 +331,8 @@ iso7816_process_fci(struct sc_card *card, struct sc_file *file,
|
|||
size_t length;
|
||||
int size;
|
||||
|
||||
file->status = SC_FILE_STATUS_UNKNOWN;
|
||||
|
||||
for (p = buf, length = buflen, end = buf + buflen;
|
||||
p < end;
|
||||
p += length, length = end - p) {
|
||||
|
@ -448,12 +453,48 @@ iso7816_process_fci(struct sc_card *card, struct sc_file *file,
|
|||
|
||||
case 0x8A:
|
||||
if (length == 1) {
|
||||
if (p[0] == 0x01)
|
||||
file->status = SC_FILE_STATUS_CREATION;
|
||||
else if (p[0] == 0x07 || p[0] == 0x05)
|
||||
file->status = SC_FILE_STATUS_ACTIVATED;
|
||||
else if (p[0] == 0x06 || p[0] == 0x04)
|
||||
file->status = SC_FILE_STATUS_INVALIDATED;
|
||||
switch (p[0]) {
|
||||
case 0:
|
||||
file->status =SC_FILE_STATUS_NO_INFO;
|
||||
break;
|
||||
case 1:
|
||||
file->status = SC_FILE_STATUS_CREATION;
|
||||
break;
|
||||
case 3:
|
||||
file->status = SC_FILE_STATUS_INITIALISATION;
|
||||
break;
|
||||
case 4:
|
||||
case 6:
|
||||
file->status = SC_FILE_STATUS_INVALIDATED;
|
||||
break;
|
||||
case 5:
|
||||
case 7:
|
||||
file->status = SC_FILE_STATUS_ACTIVATED;
|
||||
break;
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
file->status = SC_FILE_STATUS_TERMINATION;
|
||||
break;
|
||||
case 2:
|
||||
file->status = SC_FILE_STATUS_RFU_2;
|
||||
break;
|
||||
case 8:
|
||||
file->status = SC_FILE_STATUS_RFU_8;
|
||||
break;
|
||||
case 9:
|
||||
file->status = SC_FILE_STATUS_RFU_9;
|
||||
break;
|
||||
case 10:
|
||||
file->status = SC_FILE_STATUS_RFU_10;
|
||||
break;
|
||||
case 11:
|
||||
file->status = SC_FILE_STATUS_RFU_11;
|
||||
break;
|
||||
default:
|
||||
file->status = SC_FILE_STATUS_PROPRIETARY;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1017,7 +1058,7 @@ iso7816_decipher(struct sc_card *card,
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
int
|
||||
iso7816_build_pin_apdu(struct sc_card *card, struct sc_apdu *apdu,
|
||||
struct sc_pin_cmd_data *data, u8 *buf, size_t buf_len)
|
||||
{
|
||||
|
|
|
@ -114,7 +114,6 @@ sc_bytes2apdu
|
|||
sc_format_asn1_entry
|
||||
sc_format_oid
|
||||
sc_init_oid
|
||||
sc_compare_oid
|
||||
sc_valid_oid
|
||||
sc_format_path
|
||||
sc_free_apps
|
||||
|
@ -150,8 +149,6 @@ sc_pkcs15_cache_file
|
|||
sc_pkcs15_card_clear
|
||||
sc_pkcs15_card_free
|
||||
sc_pkcs15_card_new
|
||||
sc_pkcs15_tokeninfo_new
|
||||
sc_pkcs15_free_tokeninfo
|
||||
sc_pkcs15_change_pin
|
||||
sc_pkcs15_compare_id
|
||||
sc_pkcs15_compute_signature
|
||||
|
@ -178,6 +175,7 @@ sc_pkcs15_encode_pubkey
|
|||
sc_pkcs15_encode_pubkey_dsa
|
||||
sc_pkcs15_encode_pubkey_rsa
|
||||
sc_pkcs15_encode_pubkey_ec
|
||||
sc_pkcs15_encode_pubkey_eddsa
|
||||
sc_pkcs15_encode_pubkey_gostr3410
|
||||
sc_pkcs15_encode_pubkey_as_spki
|
||||
sc_pkcs15_encode_pukdf_entry
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "internal.h"
|
||||
|
||||
static void sc_do_log_va(sc_context_t *ctx, int level, const char *file, int line, const char *func, int color, const char *format, va_list args);
|
||||
static int sc_color_fprintf_va(int colors, struct sc_context *ctx, FILE * stream, const char *format, va_list args);
|
||||
|
||||
void sc_do_log(sc_context_t *ctx, int level, const char *file, int line, const char *func, const char *format, ...)
|
||||
{
|
||||
|
@ -74,7 +75,6 @@ void sc_do_log_noframe(sc_context_t *ctx, int level, const char *format, va_list
|
|||
|
||||
static void sc_do_log_va(sc_context_t *ctx, int level, const char *file, int line, const char *func, int color, const char *format, va_list args)
|
||||
{
|
||||
char buf[4096];
|
||||
#ifdef _WIN32
|
||||
SYSTEMTIME st;
|
||||
#else
|
||||
|
@ -142,11 +142,9 @@ static void sc_do_log_va(sc_context_t *ctx, int level, const char *file, int lin
|
|||
file, line, func ? func : "");
|
||||
}
|
||||
|
||||
if (vsnprintf(buf, sizeof buf, format, args) >= 0) {
|
||||
sc_color_fprintf(color, ctx, ctx->debug_file, "%s", buf);
|
||||
if (strlen(buf) == 0 || buf[strlen(buf)-1] != '\n')
|
||||
sc_color_fprintf(color, ctx, ctx->debug_file, "\n");
|
||||
}
|
||||
sc_color_fprintf_va(color, ctx, ctx->debug_file, format, args);
|
||||
if (strlen(format) == 0 || format[strlen(format) - 1] != '\n')
|
||||
sc_color_fprintf(color, ctx, ctx->debug_file, "\n");
|
||||
fflush(ctx->debug_file);
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -202,7 +200,18 @@ static int is_a_tty(FILE *fp)
|
|||
|
||||
int sc_color_fprintf(int colors, struct sc_context *ctx, FILE * stream, const char * format, ...)
|
||||
{
|
||||
int r;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
r = sc_color_fprintf_va(colors, ctx, stream, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int sc_color_fprintf_va(int colors, struct sc_context *ctx, FILE * stream, const char *format, va_list args)
|
||||
{
|
||||
int r;
|
||||
#ifdef _WIN32
|
||||
WORD old_attr = 0;
|
||||
|
@ -264,9 +273,7 @@ int sc_color_fprintf(int colors, struct sc_context *ctx, FILE * stream, const ch
|
|||
#endif
|
||||
}
|
||||
|
||||
va_start(ap, format);
|
||||
r = vfprintf(stream, format, ap);
|
||||
va_end(ap);
|
||||
r = vfprintf(stream, format, args);
|
||||
|
||||
if (colors && (!ctx || (!(ctx->flags & SC_CTX_FLAG_DISABLE_COLORS)))) {
|
||||
#ifdef _WIN32
|
||||
|
|
|
@ -78,6 +78,8 @@ extern "C" {
|
|||
#define SC_ALGORITHM_DSA 1
|
||||
#define SC_ALGORITHM_EC 2
|
||||
#define SC_ALGORITHM_GOSTR3410 3
|
||||
#define SC_ALGORITHM_EDDSA 4
|
||||
#define SC_ALGORITHM_XEDDSA 5
|
||||
|
||||
/* Symmetric algorithms */
|
||||
#define SC_ALGORITHM_DES 64
|
||||
|
@ -189,6 +191,10 @@ extern "C" {
|
|||
SC_ALGORITHM_ECDSA_HASH_SHA384 | \
|
||||
SC_ALGORITHM_ECDSA_HASH_SHA512)
|
||||
|
||||
/* EdDSA algorithms */
|
||||
#define SC_ALGORITHM_EDDSA_RAW 0x00400000
|
||||
#define SC_ALGORITHM_XEDDSA_RAW 0x00800000
|
||||
|
||||
/* define mask of all algorithms that can do raw */
|
||||
#define SC_ALGORITHM_RAW_MASK (SC_ALGORITHM_RSA_RAW | \
|
||||
SC_ALGORITHM_GOSTR3410_RAW | \
|
||||
|
@ -1555,6 +1561,10 @@ struct sc_algorithm_info * sc_card_find_rsa_alg(struct sc_card *card,
|
|||
unsigned int key_length);
|
||||
struct sc_algorithm_info * sc_card_find_ec_alg(struct sc_card *card,
|
||||
unsigned int field_length, struct sc_object_id *curve_oid);
|
||||
struct sc_algorithm_info * sc_card_find_eddsa_alg(struct sc_card *card,
|
||||
unsigned int field_length, struct sc_object_id *curve_oid);
|
||||
struct sc_algorithm_info * sc_card_find_xeddsa_alg(struct sc_card *card,
|
||||
unsigned int field_length, struct sc_object_id *curve_oid);
|
||||
struct sc_algorithm_info * sc_card_find_gostr3410_alg(struct sc_card *card,
|
||||
unsigned int key_length);
|
||||
struct sc_algorithm_info * sc_card_find_alg(sc_card_t *card,
|
||||
|
@ -1664,6 +1674,19 @@ int iso7816_update_binary_sfid(sc_card_t *card, unsigned char sfid,
|
|||
* */
|
||||
int iso7816_logout(sc_card_t *card, unsigned char pin_reference);
|
||||
|
||||
/*
|
||||
* @brief Format PIN APDU for modifiction by card driver
|
||||
*
|
||||
* @param[in] card card
|
||||
* @param[in] apdu apdu structure to update with PIN APDU
|
||||
* @param[in] data pin command data to set into the APDU
|
||||
* @param[in] buf buffer for APDU data field
|
||||
* @param[in] buf_len maximum buffer length
|
||||
*/
|
||||
int
|
||||
iso7816_build_pin_apdu(struct sc_card *card, struct sc_apdu *apdu,
|
||||
struct sc_pin_cmd_data *data, u8 *buf, size_t buf_len);
|
||||
|
||||
/**
|
||||
* Free a buffer returned by OpenSC.
|
||||
* Use this instead your C libraries free() to free memory allocated by OpenSC.
|
||||
|
|
|
@ -143,7 +143,7 @@ CERT_HANDLE_FUNCTION(default_cert_handle) {
|
|||
int r;
|
||||
X509 *cert_data = NULL;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
RSA * rsa = NULL;
|
||||
const RSA * rsa = NULL;
|
||||
int certtype = 0;
|
||||
int modulus_len = 0;
|
||||
const prdata* key = get_prkey_by_cert(items, cert);
|
||||
|
|
|
@ -491,6 +491,8 @@ int sc_get_encoding_flags(sc_context_t *ctx,
|
|||
} else if ((caps & SC_ALGORITHM_RSA_PAD_PSS) &&
|
||||
(iflags & SC_ALGORITHM_RSA_PAD_PSS)) {
|
||||
*sflags |= SC_ALGORITHM_RSA_PAD_PSS;
|
||||
*sflags |= iflags & SC_ALGORITHM_MGF1_HASHES;
|
||||
*pflags = iflags & ~(iflags & (SC_ALGORITHM_MGF1_HASHES | SC_ALGORITHM_RSA_PAD_PSS));
|
||||
|
||||
} else if ((caps & SC_ALGORITHM_RSA_RAW) &&
|
||||
(iflags & SC_ALGORITHM_RSA_PAD_PKCS1
|
||||
|
|
|
@ -412,7 +412,6 @@ static struct sc_asn1_pkcs15_algorithm_info algorithm_table[] = {
|
|||
asn1_encode_pbes2_params,
|
||||
asn1_free_pbes2_params },
|
||||
#endif
|
||||
|
||||
#ifdef SC_ALGORITHM_EC
|
||||
{ SC_ALGORITHM_EC, {{ 1, 2, 840, 10045, 2, 1, -1}},
|
||||
asn1_decode_ec_params,
|
||||
|
@ -448,6 +447,16 @@ static struct sc_asn1_pkcs15_algorithm_info algorithm_table[] = {
|
|||
asn1_decode_ec_params,
|
||||
asn1_encode_ec_params,
|
||||
asn1_free_ec_params },
|
||||
#endif
|
||||
#ifdef SC_ALGORITHM_EDDSA
|
||||
/* aka Ed25519 */
|
||||
/* RFC 8410, needed to parse/create X509 certs/pubkeys */
|
||||
{ SC_ALGORITHM_EDDSA, {{1, 3, 101, 112, -1}}, NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef SC_ALGORITHM_XEDDSA
|
||||
/* aka curve25519 */
|
||||
/* RFC 8410, needed to parse/create X509 certs/pubkeys */
|
||||
{ SC_ALGORITHM_XEDDSA, {{1, 3, 101, 110, -1}}, NULL, NULL, NULL },
|
||||
#endif
|
||||
{ -1, {{ -1 }}, NULL, NULL, NULL }
|
||||
};
|
||||
|
@ -545,7 +554,11 @@ sc_asn1_encode_algorithm_id(struct sc_context *ctx, u8 **buf, size_t *len,
|
|||
sc_format_asn1_entry(asn1_alg_id + 0, (void *) &id->oid, NULL, 1);
|
||||
|
||||
/* no parameters, write NULL tag */
|
||||
if (!id->params || !alg_info->encode)
|
||||
/* If it's EDDSA/XEDDSA, according to RFC8410, params
|
||||
* MUST be absent */
|
||||
if (id->algorithm != SC_ALGORITHM_EDDSA &&
|
||||
id->algorithm != SC_ALGORITHM_XEDDSA &&
|
||||
(!id->params || !alg_info->encode))
|
||||
asn1_alg_id[1].flags |= SC_ASN1_PRESENT;
|
||||
|
||||
r = _sc_asn1_encode(ctx, asn1_alg_id, buf, len, depth + 1);
|
||||
|
|
|
@ -79,6 +79,7 @@ static const char * cac_get_name(int type)
|
|||
switch (type) {
|
||||
case SC_CARD_TYPE_CAC_I: return ("CAC I");
|
||||
case SC_CARD_TYPE_CAC_II: return ("CAC II");
|
||||
case SC_CARD_TYPE_CAC_ALT_HID: return ("CAC ALT HID");
|
||||
default: break;
|
||||
}
|
||||
return ("CAC");
|
||||
|
|
|
@ -337,8 +337,8 @@ sc_pkcs15_get_bitstring_extension(struct sc_context *ctx,
|
|||
LOG_TEST_RET(ctx, r, "Get extension error");
|
||||
|
||||
r = sc_asn1_decode(ctx, asn1_bit_string, bit_string, bit_string_len, NULL, NULL);
|
||||
LOG_TEST_RET(ctx, r, "Decoding extension bit string");
|
||||
free(bit_string);
|
||||
LOG_TEST_RET(ctx, r, "Decoding extension bit string");
|
||||
|
||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
}
|
||||
|
|
|
@ -425,7 +425,8 @@ coolkey_get_public_key_from_certificate(sc_pkcs15_card_t *p15card, sc_cardctl_co
|
|||
sc_pkcs15_pubkey_t *key = NULL;
|
||||
int r;
|
||||
|
||||
cert_info.value.value = NULL;
|
||||
memset(&cert_info, 0, sizeof(cert_info));
|
||||
|
||||
r = coolkey_get_certificate(p15card->card, obj, &cert_info.value);
|
||||
if (r < 0) {
|
||||
goto fail;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue