diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-06-16 08:50:32 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-06-16 15:31:43 +0200 |
commit | 4ad76785ef2feec7af64f3821edd8eb67de88762 (patch) | |
tree | b2ad5e723822fb447de94a27f06360a990d014e4 | |
parent | 7df03e9c6995f2ecfdf3ed0023dbf35e015f33e2 (diff) | |
download | gnutls-4ad76785ef2feec7af64f3821edd8eb67de88762.tar.gz |
Removed support for openpgp certificates and keys
Resolves #178
Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
77 files changed, 28 insertions, 18765 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bca145d12c..15f35ee531 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -145,28 +145,6 @@ FIPS140-2/Fedora/x86_64: - build/tests/*.log - build/tests/*/*.log -openpgp/Fedora/x86_64: - stage: stage1-testing - image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD - script: - - make autoreconf - - mkdir -p build && cd build && - ../configure --enable-openpgp-authentication --disable-doc --disable-guile --disable-full-test-suite - - make -j$(nproc) - - make abi-check - - make check -j$(nproc) - tags: - - shared - except: - - tags - artifacts: - when: on_failure - paths: - - build/guile/tests/*.log - - build/tests/*.log - - build/tests/*/*.log - - build/compat_reports/* - valgrind/Fedora/x86_64: stage: stage1-testing image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD diff --git a/configure.ac b/configure.ac index 10d26204b2..d5d6ca2f3e 100644 --- a/configure.ac +++ b/configure.ac @@ -930,7 +930,6 @@ AC_CONFIG_FILES([ Makefile doc/Makefile doc/credentials/Makefile - doc/credentials/openpgp/Makefile doc/credentials/srp/Makefile doc/credentials/x509/Makefile doc/cyclo/Makefile @@ -963,8 +962,6 @@ AC_CONFIG_FILES([ lib/includes/gnutls/gnutls.h lib/minitasn1/Makefile lib/nettle/Makefile - lib/opencdk/Makefile - lib/openpgp/Makefile lib/x509/Makefile lib/unistring/Makefile po/Makefile.in @@ -1025,7 +1022,6 @@ if features are disabled) ALPN support: $ac_enable_alpn OCSP support: $ac_enable_ocsp Ses. ticket support: $ac_enable_session_tickets - OpenPGP support: $ac_enable_openpgp SRP support: $ac_enable_srp PSK support: $ac_enable_psk DHE support: $ac_enable_dhe diff --git a/doc/credentials/Makefile.am b/doc/credentials/Makefile.am index bfe0ae025a..ecdd57a106 100644 --- a/doc/credentials/Makefile.am +++ b/doc/credentials/Makefile.am @@ -19,7 +19,7 @@ # along with this file; if not, write to the Free Software Foundation, # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -SUBDIRS = openpgp srp x509 +SUBDIRS = srp x509 EXTRA_DIST = gnutls-http-serv @@ -31,6 +31,3 @@ EXTRA_DIST += srp-passwd.txt srp-tpasswd.conf EXTRA_DIST += psk-passwd.txt -EXTRA_DIST += openpgp-server.bin openpgp-server-key.bin \ - openpgp-server-key.txt openpgp-server.txt - diff --git a/doc/credentials/openpgp-server-key.bin b/doc/credentials/openpgp-server-key.bin Binary files differdeleted file mode 100644 index fa643ffd0d..0000000000 --- a/doc/credentials/openpgp-server-key.bin +++ /dev/null diff --git a/doc/credentials/openpgp-server-key.txt b/doc/credentials/openpgp-server-key.txt deleted file mode 100644 index fe53841627..0000000000 --- a/doc/credentials/openpgp-server-key.txt +++ /dev/null @@ -1,31 +0,0 @@ ------BEGIN PGP PRIVATE KEY BLOCK----- -Version: GnuPG v1.4.6 (GNU/Linux) - -lQG7BEXInlgRBAD0teb6ohIlchkHcFlmmvtVW1KXexlDfXExf8T+fOz5z354GPOX -sDq98ztCEE3hnPEOFj4NT0X3nEtrvLkhmZqrDHSbuJACB4qxeHwEbGFx7OIDW8+u -4sKxpaza1GVf1NQ7VIaQiXaGHy8Esn9SW7oNhK6z5l4TIRlm3OBt3cxU3wCgjnnO -jpGJeeo0OnZzSH+xsNLJQEcEAOmUc+7N9OhpT/gqddIgzYRr/FD0Ad6HBfABol6Q -wWCapzIxggnZJ9i+lHujpcA8idtrBU/DGhkGtW95QaHwQ8d5SvetM7Wc/xoHEP3o -HGvSGoXtfqlofastcC7eso39EBD10cpIB+gUmhe1MpaXm7A6m+KJO+2CkqE1vMkc -tmKHBACzDRrWgkV+AtGWKl3ge9RkYHKxAPc0FBrpzDrvmvvNMaIme2u/+WP/xa4T -nTjgys+pfeplHVfCO/n6nKWrVepMPE0+ZeNWzY6CsfhL7VjSN99vm7qzNHswBiJS -gCSwJXRmQcJcS9hxqLciUyVEB32zPqX24QHnsyPYaSCzEBgOnAAAnA3QL7uV8Ih4 -GuyFG3JIhrURZU89CYW0D3Rlc3QuZ251dGxzLm9yZ4hfBBMRAgAgBQJFyJ5YAhsD -BgsJCAcDAgQVAggDBBYCAwECHgECF4AACgkQrl+tPl0dFNhXHwCfXmQ5oZOWvZOC -v87vmucRcG/UlrIAl05A5ziEJrnmTx4OVFYCp2s3JCudAj0ERciedRAIAKM4vVZP -UeSNgLUXKleIy36c4d3ogWElLeFN2S8X3ywMrxjFFwOzgExhobiqYTUC7sdewBqU -TeJ7oJyFjCxPWpMq8V6oP9euVBSm8MFbJaaOysz7xFx5jmA4FRKktLGTVppCXjD3 -QlbA9sInz5KHLn1LtlMfApq709ZxIKIlbpFI6ZSTq2pUAXbD5CBJPCzFbRdyFtmh -whBE9MqydmNqtIv7tSuG8UlIuREqzdFDWlk+8LQnoHcFpTm8CRIMHLv/GLYzJ3wS -POeYF1XSYkS3Tib5FPuuSP45z0BuUBCEDMHi7cv/hh5F1TdscOThlCK8iD1B4vPh -AxjhqqMajVDE878AAwUH/20z3NM96B6fl4bI9yT/wDAkkFfO6XiqhWBJ0SLm7DeG -OLU8FYxJEQN7Obvqkzb3cqRNbbwBJnbKWgi/xCnzAhJbXFt1lMKlCFC0NmdLfbQb -lXzBB9WdY42+vCDlcEyWM/ogbZm6uVsaKpXOcKDgg1S/amikeoTrgLpE5ei98EC/ -ucxgROJOVHy3/FFSRGuGU6rKDIt4skABTv4e1s6lAEx92kEs/baYpSe+tMGnQ4XP -knbdmtFunAvkgZiWlP8pvbHk3dup8lhxvtNxvspwh3+aQQFx4XwjYQNJTL+Yd3iR -AjRJXAodLGBpqNfYzs255UUhikaq35TrTmMIUFyvcv4AAVEB20AMyHQcPwy7QnEQ -NooBEWWgCbp2MOEvZ5vcFeogSFA5VWCNe6UGXlq6EJOISQQYEQIACQUCRciedQIb -DAAKCRCuX60+XR0U2Aw4AJ0fIntwSCVnEbxskKgcrwfIpIrtUQCfUmOoEmaWa5iU -I3zib+LCy0UXtyo= -=n6h4 ------END PGP PRIVATE KEY BLOCK----- diff --git a/doc/credentials/openpgp-server.bin b/doc/credentials/openpgp-server.bin Binary files differdeleted file mode 100644 index 2774709697..0000000000 --- a/doc/credentials/openpgp-server.bin +++ /dev/null diff --git a/doc/credentials/openpgp-server.txt b/doc/credentials/openpgp-server.txt deleted file mode 100644 index eae6bf5443..0000000000 --- a/doc/credentials/openpgp-server.txt +++ /dev/null @@ -1,29 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.6 (GNU/Linux) - -mQGiBEXInlgRBAD0teb6ohIlchkHcFlmmvtVW1KXexlDfXExf8T+fOz5z354GPOX -sDq98ztCEE3hnPEOFj4NT0X3nEtrvLkhmZqrDHSbuJACB4qxeHwEbGFx7OIDW8+u -4sKxpaza1GVf1NQ7VIaQiXaGHy8Esn9SW7oNhK6z5l4TIRlm3OBt3cxU3wCgjnnO -jpGJeeo0OnZzSH+xsNLJQEcEAOmUc+7N9OhpT/gqddIgzYRr/FD0Ad6HBfABol6Q -wWCapzIxggnZJ9i+lHujpcA8idtrBU/DGhkGtW95QaHwQ8d5SvetM7Wc/xoHEP3o -HGvSGoXtfqlofastcC7eso39EBD10cpIB+gUmhe1MpaXm7A6m+KJO+2CkqE1vMkc -tmKHBACzDRrWgkV+AtGWKl3ge9RkYHKxAPc0FBrpzDrvmvvNMaIme2u/+WP/xa4T -nTjgys+pfeplHVfCO/n6nKWrVepMPE0+ZeNWzY6CsfhL7VjSN99vm7qzNHswBiJS -gCSwJXRmQcJcS9hxqLciUyVEB32zPqX24QHnsyPYaSCzEBgOnLQPdGVzdC5nbnV0 -bHMub3JniF8EExECACAFAkXInlgCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAK -CRCuX60+XR0U2FcfAJ9eZDmhk5a9k4K/zu+a5xFwb9SWsgCXTkDnOIQmueZPHg5U -VgKnazckK7kCDQRFyJ51EAgAozi9Vk9R5I2AtRcqV4jLfpzh3eiBYSUt4U3ZLxff -LAyvGMUXA7OATGGhuKphNQLux17AGpRN4nugnIWMLE9akyrxXqg/165UFKbwwVsl -po7KzPvEXHmOYDgVEqS0sZNWmkJeMPdCVsD2wifPkocufUu2Ux8CmrvT1nEgoiVu -kUjplJOralQBdsPkIEk8LMVtF3IW2aHCEET0yrJ2Y2q0i/u1K4bxSUi5ESrN0UNa -WT7wtCegdwWlObwJEgwcu/8YtjMnfBI855gXVdJiRLdOJvkU+65I/jnPQG5QEIQM -weLty/+GHkXVN2xw5OGUIryIPUHi8+EDGOGqoxqNUMTzvwADBQf/bTPc0z3oHp+X -hsj3JP/AMCSQV87peKqFYEnRIubsN4Y4tTwVjEkRA3s5u+qTNvdypE1tvAEmdspa -CL/EKfMCEltcW3WUwqUIULQ2Z0t9tBuVfMEH1Z1jjb68IOVwTJYz+iBtmbq5Wxoq -lc5woOCDVL9qaKR6hOuAukTl6L3wQL+5zGBE4k5UfLf8UVJEa4ZTqsoMi3iyQAFO -/h7WzqUATH3aQSz9tpilJ760wadDhc+Sdt2a0W6cC+SBmJaU/ym9seTd26nyWHG+ -03G+ynCHf5pBAXHhfCNhA0lMv5h3eJECNElcCh0sYGmo19jOzbnlRSGKRqrflOtO -YwhQXK9y/ohJBBgRAgAJBQJFyJ51AhsMAAoJEK5frT5dHRTYDDgAn2bLaS5n3Xy8 -Z/V2Me1st/9pqPfZAJ4+9YBnyjCq/0vosIoZabi+s92m7g== -=NkXV ------END PGP PUBLIC KEY BLOCK----- diff --git a/doc/credentials/openpgp/Makefile.am b/doc/credentials/openpgp/Makefile.am deleted file mode 100644 index d462c0c0c8..0000000000 --- a/doc/credentials/openpgp/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -EXTRA_DIST = pub.asc sec.asc cli_pub.asc cli_ring.gpg cli_sec.asc cli_ring.asc diff --git a/doc/credentials/openpgp/cli_pub.asc b/doc/credentials/openpgp/cli_pub.asc deleted file mode 100644 index 0ab058ce10..0000000000 --- a/doc/credentials/openpgp/cli_pub.asc +++ /dev/null @@ -1,18 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.0.6 (GNU/Linux) -Comment: For info see http://www.gnupg.org - -mQGiBDxnlY0RBACAsWUhi/goBvpvTBgL8fFPwBAuD04VYFEtC7+4pBp6kFsHjUR7 -TTUkBsOk2PvMHrDdv0+C4x2CH8YGP1e+O0f2yLWk8Uu+kkF12yiqbbvDEiCdeJT6 -c3vIstY8vJ9Jso5g/LB8Xggq88R7jXFS3hH+WC5v/6P6SARfzXl457cVewCgvxSf -Gsm9mFospJ0B3RGyg5MB0d8D/RQQryJCGdR2nLe4VfctPL2QBD/1XhtubqEbetaV -PxssqrJdA+eplBRT7UHokSBahM8gmSmNuSrLDujPfEtaMg6YIkB+Kq0VeJLE0cXT -ZIH29KJlI/qk1xG4K7D6B0cKaHC/L4BIoKcQLJzfTIPw3frS4jVeNaQZNHSVqZ8/ -VmOMA/9rkNtccQ4RVd9WTFoHKvT4vfiISEOIzKGmcBY9Hymq7MCci3mNe4CDImkv -ZgnjDlJAM91CX1ODthPLBqvyhnMhhxDnaDl4Nh42uPMSr9JEW2IwoIbFne10ihGT -O4lBS1C28UfSGEMm/8JBMtxAjbYy3BYzUtCMA+bGBG6Voe5i5LQlRHIuIFdobyAo -Tm8gY29tbWVudHMpIDx3aG9Ad2hvaXMub3JnPohdBBMRAgAdBQI8Z5WNBQkDwmcA -BQsHCgMEAxUDAgMWAgECF4AACgkQNRRc6qfZPD+WWACfeJnLyfbpTDB7mDh3aATb -+0PXz28AoKRdApBVM6Bty+vWyXH6HfF6ZTj+ -=m8dH ------END PGP PUBLIC KEY BLOCK----- diff --git a/doc/credentials/openpgp/cli_ring.asc b/doc/credentials/openpgp/cli_ring.asc deleted file mode 100644 index 3726de51af..0000000000 --- a/doc/credentials/openpgp/cli_ring.asc +++ /dev/null @@ -1,36 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- - -mQGiBDxnlY0RBACAsWUhi/goBvpvTBgL8fFPwBAuD04VYFEtC7+4pBp6kFsHjUR7 -TTUkBsOk2PvMHrDdv0+C4x2CH8YGP1e+O0f2yLWk8Uu+kkF12yiqbbvDEiCdeJT6 -c3vIstY8vJ9Jso5g/LB8Xggq88R7jXFS3hH+WC5v/6P6SARfzXl457cVewCgvxSf -Gsm9mFospJ0B3RGyg5MB0d8D/RQQryJCGdR2nLe4VfctPL2QBD/1XhtubqEbetaV -PxssqrJdA+eplBRT7UHokSBahM8gmSmNuSrLDujPfEtaMg6YIkB+Kq0VeJLE0cXT -ZIH29KJlI/qk1xG4K7D6B0cKaHC/L4BIoKcQLJzfTIPw3frS4jVeNaQZNHSVqZ8/ -VmOMA/9rkNtccQ4RVd9WTFoHKvT4vfiISEOIzKGmcBY9Hymq7MCci3mNe4CDImkv -ZgnjDlJAM91CX1ODthPLBqvyhnMhhxDnaDl4Nh42uPMSr9JEW2IwoIbFne10ihGT -O4lBS1C28UfSGEMm/8JBMtxAjbYy3BYzUtCMA+bGBG6Voe5i5LQlRHIuIFdobyAo -Tm8gY29tbWVudHMpIDx3aG9Ad2hvaXMub3JnPohdBBMRAgAdBQI8Z5WNBQkDwmcA -BQsHCgMEAxUDAgMWAgECF4AACgkQNRRc6qfZPD+WWACfeJnLyfbpTDB7mDh3aATb -+0PXz28AoKRdApBVM6Bty+vWyXH6HfF6ZTj+mQGiBDxKxWwRBADnLna2Lu+po71Z -QJMpJBgFDALXAp1sogZu/DTIYDhifGQ+saZSp68dN89G/FBaweDGmbN4lbS8s+U1 -Qf/aR2bWFowriq/WqyJGbQbRgDTV2saY5pk7pbNQ/4IuHNhwKnURTotzprCcs7k8 -5E27UWybtflbtmYYhgKgoURyNsBljwCgj1teeNhfeSzCBy+UdGRXJvtNk3MD/jV4 -1onWYG6RGOn5pwQrljzyPz2PE3eic8Dwl02/RLPKvL4U3WRBJVWGPjmpxidmLXes -NmYq5El5LDJi0/EumDKnVlMJ1nugrk3yX17aCTcFatW+ifQGnr1+x2zkMkQd9dUv -/9BtOeX2HjaUe2mKd8tiq4HkpBIr+QUGcdmUbIZeBADQYUN6lk3eMYgYwrJN4Ajm -AJa2DbimhLhag40Rn8kwMRiJrVejuSf0SPhOslPGI+2nO0L/eLzmOmpTHXWmTOhU -BROAjp9bEM4HXTQXuAEWSRixMdNUTIdlqOy5lx9hoJ/HPVCYBhBrWXfSEcsOHQTQ -7Za86Juuj3PYALBSE5y/jbRJT3BlbkNESyB0ZXN0IGtleSAoT25seSBpbnRlbmRl -ZCBmb3IgdGVzdCBwdXJwb3NlcyEpIDxvcGVuY2RrQGZvby1iYXIub3JnPohiBBMR -AgAaBQI8SsVsBQsHCgMEAxUDAgMWAgECHgECF4AAEgkQvVcs3MzAfDUHZUdQRwAB -AYHBAJwOEo2O1ER8bcvOYVDZzYbiDYRZpQCfZoFmLIDGqs8dLSvCBPCC/oDT26S5 -AQ0EPErFbxAEAOIBVlJgadBn0k9NcebThljgi+O/JGwa3OCNtpzY1FnB7TNXOEEH -mHVa/befF5fPAi5wx5YPEspoltJ8/SShHNMW3eH7zB6mFcXDH+xlbkZweMh1/FCb -HsuZyLVsLYdcUOIBi1sPo3hgbrZCWiUzgw9V/SHWSQFWFdSaHQnpUQ9fAAMFBADQ -va3kBDJ1hnXIfQcww2CYFGe64b62zBBaPB82a/2+oS43hFZRMji4rUFOUqKpZh0d -8dtrtfM/aQYWYQdVbIEyJDMLMJMtt8jMgiVnLXriSvJGl1DlObZh6mR10uA82NOD -jcSorEr9ITU2/j6W7J0K6mUWS1duAbN6jcqJ8rJX0IhOBBgRAgAGBQI8SsVvABIJ -EL1XLNzMwHw1B2VHUEcAAQF1ZgCfYB4fmeCwfHfmfz7soeGflGPTc2cAn2rGnrQR -mm/79Enn0VTYLgXUCGHb -=7B/E ------END PGP PUBLIC KEY BLOCK----- diff --git a/doc/credentials/openpgp/cli_ring.gpg b/doc/credentials/openpgp/cli_ring.gpg Binary files differdeleted file mode 100644 index f78440407b..0000000000 --- a/doc/credentials/openpgp/cli_ring.gpg +++ /dev/null diff --git a/doc/credentials/openpgp/cli_sec.asc b/doc/credentials/openpgp/cli_sec.asc deleted file mode 100644 index 49348ca5b8..0000000000 --- a/doc/credentials/openpgp/cli_sec.asc +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN PGP PRIVATE KEY BLOCK----- -Version: GnuPG v1.0.6 (GNU/Linux) -Comment: For info see http://www.gnupg.org - -lQG7BDxnlY0RBACAsWUhi/goBvpvTBgL8fFPwBAuD04VYFEtC7+4pBp6kFsHjUR7 -TTUkBsOk2PvMHrDdv0+C4x2CH8YGP1e+O0f2yLWk8Uu+kkF12yiqbbvDEiCdeJT6 -c3vIstY8vJ9Jso5g/LB8Xggq88R7jXFS3hH+WC5v/6P6SARfzXl457cVewCgvxSf -Gsm9mFospJ0B3RGyg5MB0d8D/RQQryJCGdR2nLe4VfctPL2QBD/1XhtubqEbetaV -PxssqrJdA+eplBRT7UHokSBahM8gmSmNuSrLDujPfEtaMg6YIkB+Kq0VeJLE0cXT -ZIH29KJlI/qk1xG4K7D6B0cKaHC/L4BIoKcQLJzfTIPw3frS4jVeNaQZNHSVqZ8/ -VmOMA/9rkNtccQ4RVd9WTFoHKvT4vfiISEOIzKGmcBY9Hymq7MCci3mNe4CDImkv -ZgnjDlJAM91CX1ODthPLBqvyhnMhhxDnaDl4Nh42uPMSr9JEW2IwoIbFne10ihGT -O4lBS1C28UfSGEMm/8JBMtxAjbYy3BYzUtCMA+bGBG6Voe5i5AAAnjMCLPrxGdgE -I0xXdwCQ4Sh2diNECAj9JiM6RFNBX2ZhY3RvcjoAAK9cun7/j4AUMmdvIy5UMJph -A6eq6atP/SYjOkRTQV9mYWN0b3I6AACvVjUuomodmmyCggPHWdeVSzpX3ODEHf0m -IzpEU0FfZmFjdG9yOgAAr2Iv9H2aSH+vJKGYW/BO4ehQwwFck7u0JURyLiBXaG8g -KE5vIGNvbW1lbnRzKSA8d2hvQHdob2lzLm9yZz6IXQQTEQIAHQUCPGeVjQUJA8Jn -AAULBwoDBAMVAwIDFgIBAheAAAoJEDUUXOqn2Tw/llgAnjBPQdWxIqBCQGlcI2K/ -gLkZR1ARAJ9kaAeJYERc0bV/vlm0ot7UDdr+bQ== -=4M0W ------END PGP PRIVATE KEY BLOCK----- diff --git a/doc/credentials/openpgp/pub.asc b/doc/credentials/openpgp/pub.asc deleted file mode 100644 index a5e795b332..0000000000 --- a/doc/credentials/openpgp/pub.asc +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.6 (GNU/Linux) - -mNEER2PogwEGINdIR4u5PR4SwADWwj/ztgtoi7XVbmlfbQTHpBYFxTSC88pISSNy -V/rgnlqunYP77F7aHL4KUReN3v9sKw01xSGEfox/JmlqUUg6CVvTjdeLfkuVIBnH -j+2KMlaxezp7IxtPaTXpXcSf8iOuVq7UX7p6tKbppKXO5GgmfA88VUVvGBs1/PQp -WKQdGrj+6I3RRmDN/hna1jGU/N23230Hbx+bu7g9cviiSh10ri7rdDhVJ67tRkRG -Usy3XO6dWC7EmzZlEO8AEQEAAbQQdGVzdDMuZ251dGxzLm9yZ4kBAAQTAQIAJgUC -R2PogwIbAwUJCWYBgAYLCQgHAwIEFQIIAwQWAgMBAh4BAheAAAoJEKAh4/gImZBR -96QGH3E3zynETuQS3++hGMvMXq2mDJeT2e8964y/ifIOBpr2K2isuLYnrtGKyxi+ -ZptyHv6ymR3bDvio50cjnoT/WK1onosOJvtijGBS+U/ooq3im7ExpeQYXc/zpYsX -OmB5m6BvdomUp2PMqdxsmOPoaRkSYx5R2Rlo/z3csodl6sp3k465Y/jg7L4gkxDz -XJM+CS1xMhcOF0gBhppqLnG67x0ow847Pydstzkw0sOqedkLPuScaHNnlAWQ7QH6 -mbbpqHJwekS4jQRHiKV8AQQA0iZ81WXypLI4ZE2+hYfBCnfMVfQF/vPgvASxhwri -GDa9Zc2f/VfakfNiwZgHH6iCeppHBiP2jljnbuOsL6f1R+0FsnyTVwHbuEU7IU2y -+J0/s0z3wcx9sx8T7brP5z5F2hdagBsD9YFGCifHDAEew4mmAisY0i2QHVIuXJFj -4RMAEQEAAYkBhwQYAQIADwUCR4ilfAIbAgUJEOrPgACoCRCgIeP4CJmQUZ0gBBkB -AgAGBQJHiKV8AAoJEIN7b7QuD+F2AEcEAKAjhO9kSOE8UuwEOKlwsWL9LUUSkHJj -c/ca0asLAerzrHsldRAcwCbWkVxBBHySw2CLFjzpgdXhwRtsytMgHaapfAPbinAW -jCPIEJx2gDZeZnTgi4DVbZn5E3UzHGyL69MEoXr5t+vpiemQFd/nGD+h/Q2A76od -gvAryRvS1Soj8bcGHjUflayXGOSvaD8P2V5Vz0hS82QZcqWxD8qUBqbcB8atokmO -IYxhKyRmO58T5Ma+iaxBTUIwee+pBYDgdH6E2dh9xLlwwzZKaCcIRCQcObkLsMVo -fZJo+m0Xf8zI57NeQF+hXJhW7lIrWgQVr8IVp/lgo76acLHfL/t1n0Nhg4r2srz2 -fpP2w5laQ0qImYLnZhGFHU+rJUyFaHfhD8/svN2LuZkO570pjV/K68EaHnEfk5b8 -jWu/euohwcCwf20M1kTo3Bg= -=Xjon ------END PGP PUBLIC KEY BLOCK----- diff --git a/doc/credentials/openpgp/sec.asc b/doc/credentials/openpgp/sec.asc deleted file mode 100644 index d5dfd3b6de..0000000000 --- a/doc/credentials/openpgp/sec.asc +++ /dev/null @@ -1,44 +0,0 @@ ------BEGIN PGP PRIVATE KEY BLOCK----- -Version: GnuPG v1.4.6 (GNU/Linux) - -lQLGBEdj6IMBBiDXSEeLuT0eEsAA1sI/87YLaIu11W5pX20Ex6QWBcU0gvPKSEkj -clf64J5arp2D++xe2hy+ClEXjd7/bCsNNcUhhH6MfyZpalFIOglb043Xi35LlSAZ -x4/tijJWsXs6eyMbT2k16V3En/Ijrlau1F+6erSm6aSlzuRoJnwPPFVFbxgbNfz0 -KVikHRq4/uiN0UZgzf4Z2tYxlPzdt9t9B28fm7u4PXL4okoddK4u63Q4VSeu7UZE -RlLMt1zunVguxJs2ZRDvABEBAAEABhwMx6crpb75ko5gXl9gsYSMj9O/YyCvU7Fi -l8FnZ0dKMz3qs7jXyFlttLjh1DzYkXN6PAN5yp3+wnbK/e5eVeNSdo2WpJOwrVWO -7pcQovHoKklAjmU98olaRhpv6BBTK+0tGUFaRrmrrYuz2xnwf3+kIpt4ahYW2dr9 -B+/pvBSVC/sv2+3PEQSsXlWCYVgkQ7WBN4GQdyjjxhQpcWdf8Z6unx4zuS3s7GGM -4WaDxmDNCFlTGdrKPQeogtS3LVF9OiRCOvIlAxDmDvnC3zAwO/IvDUHFED9x9hmK -MeVwCg8rwDMptVYN2hm+bjNzjV4pimUVd+w7edjEky0Jd/6tTH01CBUWxs9Pfup2 -cQ9zkYcVz1bwcoqeyRzFCJgi6PiVT38QFEvyusoVkwMQ747D6p7y+R52MEcIvcLb -lBXhRviz3rW+Sch4+ohUPvBU41saM5B6UcOmhdPfdvPriI4qXwFxusGWt98NN3aW -Ns2/L9kMX/SWnN6Elfj5hrrExDZ2CE60uuvfj+O/uXfO8LUDENE4vQrC399KLbJw -uCaqjqLysYA9EY/Nv8RFGkk1UM4ViW8v1/95D95F9WqochSYH8Phr3br0chDxofb -rnm6dUPE8uiriNaKWdoiUNSuvumh9lVixmRI923+4imu3scq+rlJAZ20EHRlc3Qz -LmdudXRscy5vcmeJAQAEEwECACYFAkdj6IMCGwMFCQlmAYAGCwkIBwMCBBUCCAME -FgIDAQIeAQIXgAAKCRCgIeP4CJmQUfekBh9xN88pxE7kEt/voRjLzF6tpgyXk9nv -PeuMv4nyDgaa9itorLi2J67RissYvmabch7+spkd2w74qOdHI56E/1itaJ6LDib7 -YoxgUvlP6KKt4puxMaXkGF3P86WLFzpgeZugb3aJlKdjzKncbJjj6GkZEmMeUdkZ -aP893LKHZerKd5OOuWP44Oy+IJMQ81yTPgktcTIXDhdIAYaaai5xuu8dKMPOOz8n -bLc5MNLDqnnZCz7knGhzZ5QFkO0B+pm26ahycHpEnQHXBEeIpXwBBADSJnzVZfKk -sjhkTb6Fh8EKd8xV9AX+8+C8BLGHCuIYNr1lzZ/9V9qR82LBmAcfqIJ6mkcGI/aO -WOdu46wvp/VH7QWyfJNXAdu4RTshTbL4nT+zTPfBzH2zHxPtus/nPkXaF1qAGwP1 -gUYKJ8cMAR7DiaYCKxjSLZAdUi5ckWPhEwARAQABAAP3QKGVoNi52HXEN3ttUCyB -Q1CDurh0MLDQoHomY3MGfI4VByk2YKMb2el4IJqyHrUbBYjTpHY31W2CSIdWfoTU -DIik49CQaUpR13dJXEiG4d+nyETFutEalTQI4hMjABD9l1XvZP7Ll3YWmqN8Cam5 -JY23YAy2Noqbc3AcEut4+QIA1zcv8EU1QVqOwjSybRdm6HKK/A2bMqnITeUR/ikm -IuU4lhijm/d1qS6ZBehRvvYa9MY4V7BGEQLWSlyc5aYJ/wIA+fmRv0lHSs78QSUg -uRbNv6Aa6CXEOXmG+TpIaf/RWrPmBpdG8AROBVo1wmwG8oQaIjeX3RjKXfL3HTDD -CxNg7QIA06tApdo2j1gr3IrroUwQ7yvi56ELB1Lv+W3WLN8lzCfQ6Fs+7IJRrC2R -0uzLMGOsSORGAFIbAuLIMpc6rHCeS50hiQGHBBgBAgAPBQJHiKV8AhsCBQkQ6s+A -AKgJEKAh4/gImZBRnSAEGQECAAYFAkeIpXwACgkQg3tvtC4P4XYARwQAoCOE72RI -4TxS7AQ4qXCxYv0tRRKQcmNz9xrRqwsB6vOseyV1EBzAJtaRXEEEfJLDYIsWPOmB -1eHBG2zK0yAdpql8A9uKcBaMI8gQnHaANl5mdOCLgNVtmfkTdTMcbIvr0wShevm3 -6+mJ6ZAV3+cYP6H9DYDvqh2C8CvJG9LVKiPxtwYeNR+VrJcY5K9oPw/ZXlXPSFLz -ZBlypbEPypQGptwHxq2iSY4hjGErJGY7nxPkxr6JrEFNQjB576kFgOB0foTZ2H3E -uXDDNkpoJwhEJBw5uQuwxWh9kmj6bRd/zMjns15AX6FcmFbuUitaBBWvwhWn+WCj -vppwsd8v+3WfQ2GDivayvPZ+k/bDmVpDSoiZgudmEYUdT6slTIVod+EPz+y83Yu5 -mQ7nvSmNX8rrwRoecR+TlvyNa7966iHBwLB/bQzWROjcGA== -=mZnW ------END PGP PRIVATE KEY BLOCK----- diff --git a/lib/Makefile.am b/lib/Makefile.am index 8a54d54c51..a019102384 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -45,12 +45,6 @@ AM_CPPFLAGS = \ $(LIBTASN1_CFLAGS) \ $(P11_KIT_CFLAGS) -if ENABLE_OPENPGP -SUBDIRS += opencdk -SUBDIRS += openpgp -AM_CPPFLAGS += -I$(srcdir)/opencdk -endif - if !HAVE_LIBUNISTRING SUBDIRS += unistring AM_CPPFLAGS += -I$(srcdir)/unistring/ -I$(builddir)/unistring/ @@ -166,11 +160,6 @@ if ENABLE_TROUSERS thirdparty_libadd += $(LTLIBDL) endif -if ENABLE_OPENPGP -libgnutls_la_LIBADD += openpgp/libgnutls_openpgp.la -libgnutls_la_LIBADD += opencdk/libminiopencdk.la -endif - if HAVE_LD_VERSION_SCRIPT libgnutls_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libgnutls.map else diff --git a/lib/abstract_int.h b/lib/abstract_int.h index f5ba954dc6..b3a0131eae 100644 --- a/lib/abstract_int.h +++ b/lib/abstract_int.h @@ -34,9 +34,6 @@ struct gnutls_privkey_st { #ifdef ENABLE_PKCS11 gnutls_pkcs11_privkey_t pkcs11; #endif -#ifdef ENABLE_OPENPGP - gnutls_openpgp_privkey_t openpgp; -#endif struct { gnutls_privkey_sign_func sign_func; gnutls_privkey_decrypt_func decrypt_func; @@ -65,14 +62,6 @@ struct gnutls_pubkey_st { */ gnutls_pk_params_st params; -#ifdef ENABLE_OPENPGP - uint8_t openpgp_key_id[GNUTLS_OPENPGP_KEYID_SIZE]; - unsigned int openpgp_key_id_set; - - uint8_t openpgp_key_fpr[GNUTLS_OPENPGP_V4_FINGERPRINT_SIZE]; - unsigned int openpgp_key_fpr_set:1; -#endif - unsigned int key_usage; /* bits from GNUTLS_KEY_* */ struct pin_info_st pin; diff --git a/lib/algorithms/Makefile.am b/lib/algorithms/Makefile.am index 47e5739ccc..3957323420 100644 --- a/lib/algorithms/Makefile.am +++ b/lib/algorithms/Makefile.am @@ -26,8 +26,7 @@ AM_CPPFLAGS = \ -I$(srcdir)/../includes \ -I$(builddir)/../includes \ -I$(builddir)/../../gl \ - -I$(srcdir)/.. \ - -I$(srcdir)/../opencdk + -I$(srcdir)/.. if ENABLE_MINITASN1 AM_CPPFLAGS += -I$(srcdir)/../minitasn1 diff --git a/lib/algorithms/cert_types.c b/lib/algorithms/cert_types.c index ca014507dc..a7c27e0fe3 100644 --- a/lib/algorithms/cert_types.c +++ b/lib/algorithms/cert_types.c @@ -41,8 +41,6 @@ const char *gnutls_certificate_type_get_name(gnutls_certificate_type_t if (type == GNUTLS_CRT_X509) ret = "X.509"; - if (type == GNUTLS_CRT_OPENPGP) - ret = "OPENPGP"; return ret; } @@ -63,15 +61,12 @@ gnutls_certificate_type_t gnutls_certificate_type_get_id(const char *name) if (strcasecmp(name, "X.509") == 0 || strcasecmp(name, "X509") == 0) return GNUTLS_CRT_X509; - if (strcasecmp(name, "OPENPGP") == 0) - return GNUTLS_CRT_OPENPGP; return ret; } static const gnutls_certificate_type_t supported_certificate_types[] = { GNUTLS_CRT_X509, - GNUTLS_CRT_OPENPGP, 0 }; diff --git a/lib/auth/Makefile.am b/lib/auth/Makefile.am index 9df2fa13b8..9f749b04ed 100644 --- a/lib/auth/Makefile.am +++ b/lib/auth/Makefile.am @@ -26,8 +26,7 @@ AM_CPPFLAGS = \ -I$(srcdir)/../includes \ -I$(builddir)/../includes \ -I$(builddir)/../../gl \ - -I$(srcdir)/.. \ - -I$(srcdir)/../opencdk + -I$(srcdir)/.. if ENABLE_MINITASN1 AM_CPPFLAGS += -I$(srcdir)/../minitasn1 diff --git a/lib/auth/cert.c b/lib/auth/cert.c index cf75111f9d..2b635d0975 100644 --- a/lib/auth/cert.c +++ b/lib/auth/cert.c @@ -46,16 +46,6 @@ #include <gnutls/abstract.h> #include "debug.h" -#ifdef ENABLE_OPENPGP -#include "openpgp/openpgp.h" - -static gnutls_privkey_t alloc_and_load_pgp_key(const - gnutls_openpgp_privkey_t - key, int deinit); -static gnutls_pcert_st *alloc_and_load_pgp_certs(gnutls_openpgp_crt_t cert); - -#endif - static gnutls_pcert_st *alloc_and_load_x509_certs(gnutls_x509_crt_t * certs, unsigned); static gnutls_privkey_t alloc_and_load_x509_key(gnutls_x509_privkey_t key, @@ -123,14 +113,6 @@ static int copy_certificate_auth_info(cert_auth_info_t info, gnutls_pcert_st * c info->ncerts = ncerts; info->cert_type = certs[0].type; -#ifdef ENABLE_OPENPGP - if (certs[0].type == GNUTLS_CRT_OPENPGP) { - if (keyid) - memcpy(info->subkey_id, keyid, - GNUTLS_OPENPGP_KEYID_SIZE); - } -#endif - return 0; clear: @@ -289,44 +271,6 @@ find_x509_client_cert(gnutls_session_t session, } -#ifdef ENABLE_OPENPGP -/* Locates the most appropriate openpgp cert - */ -static int -find_openpgp_cert(const gnutls_certificate_credentials_t cred, - gnutls_pk_algorithm_t * pk_algos, - int pk_algos_length, int *indx) -{ - unsigned i, j; - - *indx = -1; - - for (i = 0; i < cred->ncerts; i++) { - for (j = 0; j < cred->certs[i].cert_list_length; j++) { - - /* If the *_SIGN algorithm matches - * the cert is our cert! - */ - if ((check_pk_algo_in_list - (pk_algos, pk_algos_length, - gnutls_pubkey_get_pk_algorithm(cred->certs - [i].cert_list - [0].pubkey, - NULL)) == 0) - && (cred->certs[i].cert_list[0].type == - GNUTLS_CRT_OPENPGP)) { - *indx = i; - break; - } - } - if (*indx != -1) - break; - } - - return 0; -} -#endif - /* Returns the number of issuers in the server's * certificate request packet. */ @@ -493,19 +437,8 @@ call_get_cert_callback(gnutls_session_t session, local_certs = alloc_and_load_x509_certs(st2.cert.x509, st2.ncerts); } else { /* PGP */ - if (st2.ncerts > 1) { - gnutls_assert(); - ret = GNUTLS_E_INVALID_REQUEST; - goto cleanup; - } -#ifdef ENABLE_OPENPGP - { - local_certs = alloc_and_load_pgp_certs(st2.cert.pgp); - } -#else ret = GNUTLS_E_UNIMPLEMENTED_FEATURE; goto cleanup; -#endif } if (local_certs == NULL) { @@ -515,19 +448,6 @@ call_get_cert_callback(gnutls_session_t session, } switch (st2.key_type) { - case GNUTLS_PRIVKEY_OPENPGP: -#ifdef ENABLE_OPENPGP - if (st2.key.pgp != NULL) { - local_key = - alloc_and_load_pgp_key(st2.key.pgp, st2.deinit_all); - if (local_key == NULL) { - gnutls_assert(); - ret = GNUTLS_E_INTERNAL_ERROR; - goto cleanup; - } - } -#endif - break; case GNUTLS_PRIVKEY_PKCS11: #ifdef ENABLE_PKCS11 if (st2.key.pkcs11 != NULL) { @@ -575,12 +495,6 @@ call_get_cert_callback(gnutls_session_t session, } gnutls_free(st2.cert.x509); } - } else { -#ifdef ENABLE_OPENPGP - if (st2.deinit_all) { - gnutls_openpgp_crt_deinit(st2.cert.pgp); - } -#endif } return ret; @@ -618,9 +532,7 @@ select_client_cert(gnutls_session_t session, /* use a callback to get certificate */ - if (session->security_parameters.cert_type != GNUTLS_CRT_X509) - issuers_dn_length = 0; - else { + if (session->security_parameters.cert_type == GNUTLS_CRT_X509) { issuers_dn_length = get_issuers_num(session, data, data_size); if (issuers_dn_length < 0) { @@ -646,6 +558,8 @@ select_client_cert(gnutls_session_t session, goto cleanup; } } + } else { + issuers_dn_length = 0; } result = @@ -657,20 +571,13 @@ select_client_cert(gnutls_session_t session, } else { /* If we have no callbacks, try to guess. */ - result = 0; - - if (session->security_parameters.cert_type == GNUTLS_CRT_X509) + if (session->security_parameters.cert_type == GNUTLS_CRT_X509) { result = find_x509_client_cert(session, cred, _data, _data_size, pk_algos, pk_algos_length, &indx); -#ifdef ENABLE_OPENPGP - else if (session->security_parameters.cert_type == - GNUTLS_CRT_OPENPGP) - result = - find_openpgp_cert(cred, pk_algos, - pk_algos_length, &indx); -#endif - + } else { + result = GNUTLS_E_UNIMPLEMENTED_FEATURE; + } if (result < 0) { gnutls_assert(); return result; @@ -750,171 +657,12 @@ static int gen_x509_crt(gnutls_session_t session, gnutls_buffer_st * data) return data->length; } -enum PGPKeyDescriptorType - { PGP_EMPTY_KEY = 1, PGP_KEY_SUBKEY, PGP_KEY_FINGERPRINT_SUBKEY }; - -#ifdef ENABLE_OPENPGP -static int -gen_openpgp_certificate(gnutls_session_t session, gnutls_buffer_st * data) -{ - int ret; - gnutls_pcert_st *apr_cert_list; - gnutls_privkey_t apr_pkey; - int apr_cert_list_length; - unsigned int subkey; - uint8_t type; - uint8_t fpr[GNUTLS_OPENPGP_V4_FINGERPRINT_SIZE]; - char buf[2 * GNUTLS_OPENPGP_KEYID_SIZE + 1]; - size_t fpr_size; - - /* find the appropriate certificate */ - if ((ret = - _gnutls_get_selected_cert(session, &apr_cert_list, - &apr_cert_list_length, &apr_pkey)) < 0) { - gnutls_assert(); - return ret; - } - - ret = 3 + 1 + 3; - - if (apr_cert_list_length > 0) { - fpr_size = sizeof(fpr); - ret = - gnutls_pubkey_get_openpgp_key_id(apr_cert_list[0].pubkey, 0, - fpr, &fpr_size, &subkey); - if (ret < 0) - return gnutls_assert_val(ret); - - ret += 1 + fpr_size; /* for the keyid */ - _gnutls_handshake_log("Sending PGP key ID %s (%s)\n", - _gnutls_bin2hex(fpr, - GNUTLS_OPENPGP_KEYID_SIZE, - buf, sizeof(buf), - NULL), - subkey ? "subkey" : "master"); - - ret += apr_cert_list[0].cert.size; - } - - ret = _gnutls_buffer_append_prefix(data, 24, ret - 3); - if (ret < 0) - return gnutls_assert_val(ret); - - if (apr_cert_list_length > 0) { - type = PGP_KEY_SUBKEY; - - ret = _gnutls_buffer_append_data(data, &type, 1); - if (ret < 0) - return gnutls_assert_val(ret); - - ret = _gnutls_buffer_append_data_prefix(data, 8, fpr, fpr_size); - if (ret < 0) - return gnutls_assert_val(ret); - - ret = - _gnutls_buffer_append_data_prefix(data, 24, - apr_cert_list[0]. - cert.data, - apr_cert_list[0]. - cert.size); - if (ret < 0) - return gnutls_assert_val(ret); - } else { /* empty - no certificate */ - - type = PGP_EMPTY_KEY; - - ret = _gnutls_buffer_append_data(data, &type, 1); - if (ret < 0) - return gnutls_assert_val(ret); - - ret = _gnutls_buffer_append_prefix(data, 24, 0); - if (ret < 0) - return gnutls_assert_val(ret); - } - - return data->length; -} - -static int -gen_openpgp_certificate_fpr(gnutls_session_t session, gnutls_buffer_st * data) -{ - int ret, packet_size; - uint8_t type, fpr[GNUTLS_OPENPGP_V4_FINGERPRINT_SIZE]; - uint8_t id[GNUTLS_OPENPGP_KEYID_SIZE]; - unsigned int subkey; - size_t fpr_size, id_size; - gnutls_pcert_st *apr_cert_list; - gnutls_privkey_t apr_pkey; - int apr_cert_list_length; - - /* find the appropriate certificate */ - if ((ret = - _gnutls_get_selected_cert(session, &apr_cert_list, - &apr_cert_list_length, &apr_pkey)) < 0) { - gnutls_assert(); - return ret; - } - - if (apr_cert_list_length <= 0) - return gen_openpgp_certificate(session, data); - - id_size = sizeof(id); - ret = - gnutls_pubkey_get_openpgp_key_id(apr_cert_list[0].pubkey, 0, - id, &id_size, &subkey); - if (ret < 0) - return gnutls_assert_val(ret); - - fpr_size = sizeof(fpr); - ret = - gnutls_pubkey_get_openpgp_key_id(apr_cert_list[0].pubkey, - GNUTLS_PUBKEY_GET_OPENPGP_FINGERPRINT, - fpr, &fpr_size, NULL); - if (ret < 0) - return gnutls_assert_val(ret); - - packet_size = 3 + 1; - packet_size += 1 + fpr_size; /* for the keyid */ - - /* Only v4 fingerprints are sent - */ - packet_size += 20 + 1; - - ret = _gnutls_buffer_append_prefix(data, 24, packet_size - 3); - if (ret < 0) - return gnutls_assert_val(ret); - - type = PGP_KEY_FINGERPRINT_SUBKEY; - ret = _gnutls_buffer_append_data(data, &type, 1); - if (ret < 0) - return gnutls_assert_val(ret); - - ret = _gnutls_buffer_append_data_prefix(data, 8, id, id_size); - if (ret < 0) - return gnutls_assert_val(ret); - - ret = _gnutls_buffer_append_data_prefix(data, 8, fpr, fpr_size); - if (ret < 0) - return gnutls_assert_val(ret); - - return data->length; -} -#endif - int _gnutls_gen_cert_client_crt(gnutls_session_t session, gnutls_buffer_st * data) { switch (session->security_parameters.cert_type) { -#ifdef ENABLE_OPENPGP - case GNUTLS_CRT_OPENPGP: - if (_gnutls_openpgp_send_fingerprint(session) == 0) - return gen_openpgp_certificate(session, data); - else - return gen_openpgp_certificate_fpr(session, data); -#endif case GNUTLS_CRT_X509: return gen_x509_crt(session, data); - default: gnutls_assert(); return GNUTLS_E_INTERNAL_ERROR; @@ -925,10 +673,6 @@ int _gnutls_gen_cert_server_crt(gnutls_session_t session, gnutls_buffer_st * data) { switch (session->security_parameters.cert_type) { -#ifdef ENABLE_OPENPGP - case GNUTLS_CRT_OPENPGP: - return gen_openpgp_certificate(session, data); -#endif case GNUTLS_CRT_X509: return gen_x509_crt(session, data); default: @@ -1104,199 +848,6 @@ _gnutls_proc_x509_server_crt(gnutls_session_t session, } -#ifdef ENABLE_OPENPGP -static int -_gnutls_proc_openpgp_server_crt(gnutls_session_t session, - uint8_t * data, size_t data_size) -{ - int size, ret, len; - uint8_t *p = data; - cert_auth_info_t info; - gnutls_certificate_credentials_t cred; - ssize_t dsize = data_size; - int key_type; - gnutls_pcert_st *peer_certificate_list = NULL; - gnutls_datum_t tmp, akey = { NULL, 0 }; - unsigned int compat = 0; - uint8_t subkey_id[GNUTLS_OPENPGP_KEYID_SIZE]; - - cred = (gnutls_certificate_credentials_t) - _gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE); - if (cred == NULL) { - gnutls_assert(); - return GNUTLS_E_INSUFFICIENT_CREDENTIALS; - } - - if ((ret = - _gnutls_auth_info_set(session, GNUTLS_CRD_CERTIFICATE, - sizeof(cert_auth_info_st), 1)) < 0) { - gnutls_assert(); - return ret; - } - - info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE); - - if (data == NULL || data_size == 0) { - gnutls_assert(); - return GNUTLS_E_NO_CERTIFICATE_FOUND; - } - - DECR_LEN(dsize, 3); - size = _gnutls_read_uint24(p); - p += 3; - - if (size == 0) { - gnutls_assert(); - /* no certificate was sent */ - return GNUTLS_E_NO_CERTIFICATE_FOUND; - } - - /* Read PGPKeyDescriptor */ - DECR_LEN(dsize, 1); - key_type = *p; - p++; - - /* Try to read the keyid if present */ - if (key_type == PGP_KEY_FINGERPRINT_SUBKEY - || key_type == PGP_KEY_SUBKEY) { - /* check size */ - if (*p != GNUTLS_OPENPGP_KEYID_SIZE) { - gnutls_assert(); - return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE; - } - - DECR_LEN(dsize, 1); - p++; - - DECR_LEN(dsize, GNUTLS_OPENPGP_KEYID_SIZE); - memcpy(subkey_id, p, GNUTLS_OPENPGP_KEYID_SIZE); - p += GNUTLS_OPENPGP_KEYID_SIZE; - } - - if (key_type == PGP_KEY_FINGERPRINT_SUBKEY) { - DECR_LEN(dsize, 1); - len = (uint8_t) * p; - p++; - - if (len != 20) { - gnutls_assert(); - return GNUTLS_E_OPENPGP_FINGERPRINT_UNSUPPORTED; - } - - DECR_LEN(dsize, 20); - - /* request the actual key from our database, or - * a key server or anything. - */ - if ((ret = - _gnutls_openpgp_request_key(session, &akey, cred, p, - 20)) < 0) { - gnutls_assert(); - return ret; - } - tmp = akey; - } else if (key_type == PGP_KEY_SUBKEY) { /* the whole key */ - - /* Read the actual certificate */ - DECR_LEN(dsize, 3); - len = _gnutls_read_uint24(p); - p += 3; - - if (len == 0) { - gnutls_assert(); - /* no certificate was sent */ - return - gnutls_assert_val - (GNUTLS_E_UNEXPECTED_PACKET_LENGTH); - } - - DECR_LEN(dsize, len); - - tmp.size = len; - tmp.data = p; - - } else if (key_type == PGP_EMPTY_KEY) { /* the whole key */ - - /* Read the actual certificate */ - DECR_LEN(dsize, 3); - len = _gnutls_read_uint24(p); - p += 3; - - if (len == 0) /* PGP_EMPTY_KEY */ - return GNUTLS_E_NO_CERTIFICATE_FOUND; - /* Uncomment to remove compatibility with RFC5081. - else - return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH); */ - - DECR_LEN(dsize, len); - - tmp.size = len; - tmp.data = p; - - compat = 1; - } else { - gnutls_assert(); - return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE; - } - - if (dsize != 0) - return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH); - - /* ok we now have the peer's key in tmp datum - */ - peer_certificate_list = gnutls_calloc(1, sizeof(gnutls_pcert_st)); - if (peer_certificate_list == NULL) { - gnutls_assert(); - ret = GNUTLS_E_MEMORY_ERROR; - goto cleanup; - } - - ret = - gnutls_pcert_import_openpgp_raw(&peer_certificate_list[0], - &tmp, - GNUTLS_OPENPGP_FMT_RAW, - (compat == - 0) ? subkey_id : NULL, 0); - if (ret < 0) { - gnutls_assert(); - goto cleanup; - } - - if (compat != 0) { - size_t t = sizeof(subkey_id); - gnutls_pubkey_get_openpgp_key_id(peer_certificate_list - [0].pubkey, 0, subkey_id, &t, - NULL); - } - - ret = check_pk_compat(session, peer_certificate_list[0].pubkey); - if (ret < 0) { - gnutls_assert(); - goto cleanup; - } - - ret = - copy_certificate_auth_info(info, - peer_certificate_list, 1, subkey_id); - if (ret < 0) { - gnutls_assert(); - goto cleanup; - } - - ret = 0; - - cleanup: - - _gnutls_free_datum(&akey); - if (peer_certificate_list != NULL) { - gnutls_pcert_deinit(&peer_certificate_list[0]); - gnutls_free(peer_certificate_list); - } - return ret; - -} -#endif - int _gnutls_proc_crt(gnutls_session_t session, uint8_t * data, size_t data_size) { int ret; @@ -1311,11 +862,6 @@ int _gnutls_proc_crt(gnutls_session_t session, uint8_t * data, size_t data_size) } switch (session->security_parameters.cert_type) { -#ifdef ENABLE_OPENPGP - case GNUTLS_CRT_OPENPGP: - ret = _gnutls_proc_openpgp_server_crt(session, data, data_size); - break; -#endif case GNUTLS_CRT_X509: ret = _gnutls_proc_x509_server_crt(session, data, data_size); break; @@ -1420,12 +966,6 @@ _gnutls_proc_cert_cert_req(gnutls_session_t session, uint8_t * data, size = _gnutls_read_uint16(p); p += 2; - if (session->security_parameters.cert_type == GNUTLS_CRT_OPENPGP - && size != 0) { - gnutls_assert(); - return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; - } - DECR_LEN_FINAL(dsize, size); /* We should reply with a certificate message, @@ -1777,73 +1317,6 @@ alloc_and_load_x509_key(gnutls_x509_privkey_t key, int deinit) return local_key; } -/* converts the given pgp certificate to gnutls_cert* and allocates - * space for them. - */ -#ifdef ENABLE_OPENPGP -static gnutls_pcert_st *alloc_and_load_pgp_certs(gnutls_openpgp_crt_t cert) -{ - gnutls_pcert_st *local_certs; - int ret = 0; - - if (cert == NULL) - return NULL; - - local_certs = gnutls_malloc(sizeof(gnutls_pcert_st)); - if (local_certs == NULL) { - gnutls_assert(); - return NULL; - } - - ret = gnutls_pcert_import_openpgp(local_certs, cert, 0); - if (ret < 0) { - gnutls_assert(); - return NULL; - } - - if (ret < 0) { - gnutls_assert(); - gnutls_pcert_deinit(local_certs); - gnutls_free(local_certs); - return NULL; - } - - return local_certs; -} - -/* converts the given raw key to gnutls_privkey* and allocates - * space for it. - */ -static gnutls_privkey_t -alloc_and_load_pgp_key(gnutls_openpgp_privkey_t key, int deinit) -{ - gnutls_privkey_t local_key; - int ret = 0; - - if (key == NULL) - return NULL; - - ret = gnutls_privkey_init(&local_key); - if (ret < 0) { - gnutls_assert(); - return NULL; - } - - ret = - gnutls_privkey_import_openpgp(local_key, key, - deinit ? - GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE - : 0); - if (ret < 0) { - gnutls_assert(); - gnutls_privkey_deinit(local_key); - return NULL; - } - - return local_key; -} -#endif - #ifdef ENABLE_PKCS11 /* converts the given raw key to gnutls_privkey* and allocates diff --git a/lib/auth/cert.h b/lib/auth/cert.h index f1389fb3f6..262c2773ab 100644 --- a/lib/auth/cert.h +++ b/lib/auth/cert.h @@ -25,7 +25,6 @@ #include "auth.h" #include <auth/dh_common.h> #include <x509/x509_int.h> -#include <openpgp/openpgp_int.h> #include <gnutls/abstract.h> #include <gnutls/compat.h> #include <str_array.h> @@ -61,11 +60,6 @@ typedef struct gnutls_certificate_credentials_st { * cert_list[i][0]. */ -#ifdef ENABLE_OPENPGP - /* OpenPGP specific stuff */ - gnutls_openpgp_keyring_t keyring; -#endif - /* X509 specific stuff */ gnutls_x509_trust_list_t tlist; unsigned flags; /* gnutls_certificate_flags */ @@ -111,9 +105,6 @@ typedef struct cert_auth_info_st { unsigned int ncerts; /* holds the size of the list above */ gnutls_certificate_type_t cert_type; -#ifdef ENABLE_OPENPGP - uint8_t subkey_id[GNUTLS_OPENPGP_KEYID_SIZE]; -#endif } *cert_auth_info_t; typedef struct cert_auth_info_st cert_auth_info_st; diff --git a/lib/cert-session.c b/lib/cert-session.c index a2315389ef..51b249f78f 100644 --- a/lib/cert-session.c +++ b/lib/cert-session.c @@ -107,38 +107,6 @@ const gnutls_datum_t *gnutls_certificate_get_peers(gnutls_session_t return info->raw_certificate_list; } -#ifdef ENABLE_OPENPGP -/** - * gnutls_certificate_get_peers_subkey_id: - * @session: is a gnutls session - * @id: will contain the ID - * - * Get the peer's subkey ID when OpenPGP certificates are - * used. The returned @id should be treated as constant. - * - * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise - * an error code is returned. - * - * Since: 3.1.3 - **/ -int gnutls_certificate_get_peers_subkey_id(gnutls_session_t session, - gnutls_datum_t * id) -{ - cert_auth_info_t info; - - CHECK_AUTH(GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST); - - info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE); - if (info == NULL) - return GNUTLS_E_INVALID_REQUEST; - - id->data = info->subkey_id; - id->size = GNUTLS_OPENPGP_KEYID_SIZE; - - return 0; -} -#endif - /** * gnutls_certificate_client_get_request_status: * @session: is a gnutls session diff --git a/lib/cert.c b/lib/cert.c index c0c90f82e4..e6822e71ce 100644 --- a/lib/cert.c +++ b/lib/cert.c @@ -40,9 +40,6 @@ #include <str_array.h> #include <x509/verify-high.h> #include "x509/x509_int.h" -#ifdef ENABLE_OPENPGP -#include "openpgp/openpgp.h" -#endif #include "dh.h" /** @@ -202,9 +199,7 @@ gnutls_certificate_free_credentials(gnutls_certificate_credentials_t sc) gnutls_x509_trust_list_deinit(sc->tlist, 1); gnutls_certificate_free_keys(sc); memset(sc->pin_tmp, 0, sizeof(sc->pin_tmp)); -#ifdef ENABLE_OPENPGP - gnutls_openpgp_keyring_deinit(sc->keyring); -#endif + if (sc->deinit_dh_params) { gnutls_dh_params_deinit(sc->dh_params); } @@ -564,73 +559,6 @@ _gnutls_x509_get_raw_crt_expiration_time(const gnutls_datum_t * cert) return result; } -#ifdef ENABLE_OPENPGP -/*- - * _gnutls_openpgp_crt_verify_peers - return the peer's certificate status - * @session: is a gnutls session - * - * This function will try to verify the peer's certificate and return its status (TRUSTED, INVALID etc.). - * Returns a negative error code in case of an error, or GNUTLS_E_NO_CERTIFICATE_FOUND if no certificate was sent. - -*/ -static int -_gnutls_openpgp_crt_verify_peers(gnutls_session_t session, - gnutls_x509_subject_alt_name_t type, - const char *hostname, - unsigned int *status) -{ - cert_auth_info_t info; - gnutls_certificate_credentials_t cred; - int peer_certificate_list_size, ret; - unsigned int verify_flags; - - CHECK_AUTH(GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST); - - info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE); - if (info == NULL) - return GNUTLS_E_INVALID_REQUEST; - - cred = (gnutls_certificate_credentials_t) - _gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE); - if (cred == NULL) { - gnutls_assert(); - return GNUTLS_E_INSUFFICIENT_CREDENTIALS; - } - - if (info->raw_certificate_list == NULL || info->ncerts == 0) { - gnutls_assert(); - return GNUTLS_E_NO_CERTIFICATE_FOUND; - } - - verify_flags = cred->verify_flags | session->internals.additional_verify_flags; - - /* generate a list of gnutls_certs based on the auth info - * raw certs. - */ - peer_certificate_list_size = info->ncerts; - - if (peer_certificate_list_size != 1) { - gnutls_assert(); - return GNUTLS_E_INTERNAL_ERROR; - } - - /* Verify certificate - */ - ret = - _gnutls_openpgp_verify_key(cred, type, hostname, - &info->raw_certificate_list[0], - peer_certificate_list_size, - verify_flags, - status); - - if (ret < 0) { - gnutls_assert(); - return ret; - } - - return 0; -} -#endif - /** * gnutls_certificate_verify_peers2: * @session: is a gnutls session @@ -764,28 +692,6 @@ gnutls_certificate_verify_peers(gnutls_session_t session, case GNUTLS_CRT_X509: return _gnutls_x509_cert_verify_peers(session, data, elements, status); -#ifdef ENABLE_OPENPGP - case GNUTLS_CRT_OPENPGP: { - const char *hostname = NULL; - unsigned i, type = 0; - - for (i=0;i<elements;i++) { - if (data[i].type == GNUTLS_DT_DNS_HOSTNAME) { - hostname = (char*)data[i].data; - type = GNUTLS_SAN_DNSNAME; - break; - } else if (data[i].type == GNUTLS_DT_RFC822NAME) { - hostname = (char*)data[i].data; - type = GNUTLS_SAN_RFC822NAME; - break; - } - } - return _gnutls_openpgp_crt_verify_peers(session, - type, - hostname, - status); - } -#endif default: return GNUTLS_E_INVALID_REQUEST; } @@ -823,12 +729,6 @@ time_t gnutls_certificate_expiration_time_peers(gnutls_session_t session) _gnutls_x509_get_raw_crt_expiration_time(&info-> raw_certificate_list [0]); -#ifdef ENABLE_OPENPGP - case GNUTLS_CRT_OPENPGP: - return - _gnutls_openpgp_get_raw_key_expiration_time - (&info->raw_certificate_list[0]); -#endif default: return (time_t) - 1; } @@ -839,7 +739,6 @@ time_t gnutls_certificate_expiration_time_peers(gnutls_session_t session) * @session: is a gnutls session * * This function will return the peer's certificate activation time. - * This is the creation time for openpgp keys. * * Returns: (time_t)-1 on error. * @@ -867,13 +766,6 @@ time_t gnutls_certificate_activation_time_peers(gnutls_session_t session) _gnutls_x509_get_raw_crt_activation_time(&info-> raw_certificate_list [0]); -#ifdef ENABLE_OPENPGP - case GNUTLS_CRT_OPENPGP: - return - _gnutls_openpgp_get_raw_key_creation_time(&info-> - raw_certificate_list - [0]); -#endif default: return (time_t) - 1; } @@ -1007,16 +899,6 @@ gnutls_certificate_verification_status_print(unsigned int status, _gnutls_buffer_append_str(&str, _ ("The certificate issuer is not a CA. ")); - } else if (type == GNUTLS_CRT_OPENPGP) { - if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) - _gnutls_buffer_append_str(&str, - _ - ("Could not find a signer of the certificate. ")); - - if (status & GNUTLS_CERT_REVOKED) - _gnutls_buffer_append_str(&str, - _ - ("The certificate is revoked. ")); } if (status & GNUTLS_CERT_INSECURE_ALGORITHM) diff --git a/lib/crypto-backend.h b/lib/crypto-backend.h index ef555d7382..92e3092d8d 100644 --- a/lib/crypto-backend.h +++ b/lib/crypto-backend.h @@ -87,7 +87,6 @@ typedef void *bigint_t; * @GNUTLS_MPI_FORMAT_USG: Raw unsigned integer format. * @GNUTLS_MPI_FORMAT_STD: Raw signed integer format, always a leading * zero when positive. - * @GNUTLS_MPI_FORMAT_PGP: The pgp integer format. * * Enumeration of different bignum integer encoding formats. */ @@ -95,9 +94,7 @@ typedef enum { /* raw unsigned integer format */ GNUTLS_MPI_FORMAT_USG = 0, /* raw signed integer format - always a leading zero when positive */ - GNUTLS_MPI_FORMAT_STD = 1, - /* the pgp integer format */ - GNUTLS_MPI_FORMAT_PGP = 2 + GNUTLS_MPI_FORMAT_STD = 1 } gnutls_bigint_format_t; /* Multi precision integer arithmetic */ diff --git a/lib/ext/Makefile.am b/lib/ext/Makefile.am index fa3b90dbee..698e41667e 100644 --- a/lib/ext/Makefile.am +++ b/lib/ext/Makefile.am @@ -26,8 +26,7 @@ AM_CPPFLAGS = \ -I$(srcdir)/../includes \ -I$(builddir)/../includes \ -I$(builddir)/../../gl \ - -I$(srcdir)/.. \ - -I$(srcdir)/../opencdk + -I$(srcdir)/.. if ENABLE_MINITASN1 AM_CPPFLAGS += -I$(srcdir)/../minitasn1 @@ -35,9 +34,9 @@ endif noinst_LTLIBRARIES = libgnutls_ext.la -libgnutls_ext_la_SOURCES = max_record.c cert_type.c \ +libgnutls_ext_la_SOURCES = max_record.c \ server_name.c signature.c safe_renegotiation.c \ - max_record.h cert_type.h server_name.h srp.h \ + max_record.h server_name.h srp.h \ session_ticket.h signature.h safe_renegotiation.h \ session_ticket.c srp.c ecc.c ecc.h heartbeat.c heartbeat.h \ status_request.h status_request.c dumbfw.c dumbfw.h \ diff --git a/lib/ext/cert_type.c b/lib/ext/cert_type.c deleted file mode 100644 index ffaa0e0155..0000000000 --- a/lib/ext/cert_type.c +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (C) 2002-2012 Free Software Foundation, Inc. - * - * Author: Nikos Mavrogiannopoulos - * - * This file is part of GnuTLS. - * - * The GnuTLS 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -/* This file contains the code the Certificate Type TLS extension. - * This extension is currently gnutls specific. - */ - -#include "gnutls_int.h" -#include "errors.h" -#include "num.h" -#include <ext/cert_type.h> -#include <state.h> -#include <num.h> - -#ifdef ENABLE_OPENPGP - -/* Maps record size to numbers according to the - * extensions draft. - */ -inline static int _gnutls_num2cert_type(int num); -inline static int _gnutls_cert_type2num(int record_size); -static int _gnutls_cert_type_recv_params(gnutls_session_t session, - const uint8_t * data, - size_t data_size); -static int _gnutls_cert_type_send_params(gnutls_session_t session, - gnutls_buffer_st * extdata); - -const extension_entry_st ext_mod_cert_type = { - .name = "Certificate Type", - .type = GNUTLS_EXTENSION_CERT_TYPE, - .parse_type = GNUTLS_EXT_TLS, - - .recv_func = _gnutls_cert_type_recv_params, - .send_func = _gnutls_cert_type_send_params, - .pack_func = NULL, - .unpack_func = NULL, - .deinit_func = NULL, - .cannot_be_overriden = 1 -}; - -/* - * In case of a server: if a CERT_TYPE extension type is received then it stores - * into the session security parameters the new value. The server may use gnutls_session_certificate_type_get(), - * to access it. - * - * In case of a client: If a cert_types have been specified then we send the extension. - * - */ - -static int -_gnutls_cert_type_recv_params(gnutls_session_t session, - const uint8_t * data, size_t _data_size) -{ - int new_type = -1, ret, i; - ssize_t data_size = _data_size; - - if (session->security_parameters.entity == GNUTLS_CLIENT) { - if (data_size > 0) { - if (data_size != 1) { - gnutls_assert(); - return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; - } - - new_type = _gnutls_num2cert_type(data[0]); - - if (new_type < 0) { - gnutls_assert(); - return new_type; - } - - /* Check if we support this cert_type */ - if ((ret = - _gnutls_session_cert_type_supported(session, - new_type)) - < 0) { - gnutls_assert(); - return ret; - } - - _gnutls_session_cert_type_set(session, new_type); - } - } else { /* SERVER SIDE - we must check if the sent cert type is the right one - */ - if (data_size > 1) { - uint8_t len; - - DECR_LEN(data_size, 1); - len = data[0]; - DECR_LEN(data_size, len); - - for (i = 0; i < len; i++) { - new_type = - _gnutls_num2cert_type(data[i + 1]); - - if (new_type < 0) - continue; - - /* Check if we support this cert_type */ - if ((ret = - _gnutls_session_cert_type_supported - (session, new_type)) < 0) { - gnutls_assert(); - continue; - } else - break; - /* new_type is ok */ - } - - if (new_type < 0) { - gnutls_assert(); - return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER; - } - - if ((ret = - _gnutls_session_cert_type_supported(session, - new_type)) - < 0) { - gnutls_assert(); - /* The peer has requested unsupported certificate - * types. Instead of failing, procceed normally. - * (the ciphersuite selection would fail, or a - * non certificate ciphersuite will be selected). - */ - return 0; - } - - _gnutls_session_cert_type_set(session, new_type); - } - } - - return 0; -} - -/* returns data_size or a negative number on failure - */ -static int -_gnutls_cert_type_send_params(gnutls_session_t session, - gnutls_buffer_st * extdata) -{ - unsigned len, i; - int ret; - uint8_t p; - - /* this function sends the client extension data (dnsname) */ - if (session->security_parameters.entity == GNUTLS_CLIENT) { - - if (session->internals.priorities.cert_type.algorithms > 0) { - - len = - session->internals.priorities.cert_type. - algorithms; - - if (len == 1 && - session->internals.priorities.cert_type. - priority[0] == GNUTLS_CRT_X509) { - /* We don't use this extension if X.509 certificates - * are used. - */ - return 0; - } - - /* this is a vector! - */ - p = (uint8_t) len; - ret = _gnutls_buffer_append_data(extdata, &p, 1); - if (ret < 0) - return gnutls_assert_val(ret); - - for (i = 0; i < len; i++) { - p = _gnutls_cert_type2num(session-> - internals. - priorities.cert_type. - priority[i]); - ret = - _gnutls_buffer_append_data(extdata, &p, - 1); - if (ret < 0) - return gnutls_assert_val(ret); - } - return len + 1; - } - - } else { /* server side */ - if (session->security_parameters.cert_type != - DEFAULT_CERT_TYPE) { - len = 1; - - p = _gnutls_cert_type2num(session-> - security_parameters. - cert_type); - ret = _gnutls_buffer_append_data(extdata, &p, 1); - if (ret < 0) - return gnutls_assert_val(ret); - - return len; - } - - - } - - return 0; -} - -/* Maps numbers to record sizes according to the - * extensions draft. - */ -inline static int _gnutls_num2cert_type(int num) -{ - switch (num) { - case 0: - return GNUTLS_CRT_X509; - case 1: - return GNUTLS_CRT_OPENPGP; - default: - return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER; - } -} - -/* Maps record size to numbers according to the - * extensions draft. - */ -inline static int _gnutls_cert_type2num(int cert_type) -{ - switch (cert_type) { - case GNUTLS_CRT_X509: - return 0; - case GNUTLS_CRT_OPENPGP: - return 1; - default: - return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER; - } - -} - -#endif diff --git a/lib/ext/cert_type.h b/lib/ext/cert_type.h deleted file mode 100644 index 8b41f586c0..0000000000 --- a/lib/ext/cert_type.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2002-2012 Free Software Foundation, Inc. - * - * Author: Nikos Mavrogiannopoulos - * - * This file is part of GnuTLS. - * - * The GnuTLS 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef EXT_CERT_TYPE_H -#define EXT_CERT_TYPE_H - -#include <extensions.h> - -extern const extension_entry_st ext_mod_cert_type; - -#endif diff --git a/lib/extensions.c b/lib/extensions.c index e232d89e0c..f19501d8d7 100644 --- a/lib/extensions.c +++ b/lib/extensions.c @@ -30,7 +30,6 @@ #include "extensions.h" #include "errors.h" #include "ext/max_record.h" -#include <ext/cert_type.h> #include <ext/server_name.h> #include <ext/srp.h> #include <ext/heartbeat.h> @@ -60,9 +59,6 @@ static extension_entry_st const *extfunc[MAX_EXT_TYPES+1] = { #ifdef ENABLE_OCSP &ext_mod_status_request, #endif -#ifdef ENABLE_OPENPGP - &ext_mod_cert_type, -#endif &ext_mod_server_name, &ext_mod_sr, #ifdef ENABLE_SRP diff --git a/lib/extras/Makefile.am b/lib/extras/Makefile.am index d9039f3d40..a22eb27238 100644 --- a/lib/extras/Makefile.am +++ b/lib/extras/Makefile.am @@ -26,8 +26,7 @@ AM_CPPFLAGS = \ -I$(srcdir)/../includes \ -I$(builddir)/../includes \ -I$(builddir)/../../gl \ - -I$(srcdir)/.. \ - -I$(srcdir)/../opencdk + -I$(srcdir)/.. EXTRA_DIST = licenses/CC0 diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 979c6822b5..b7f491c52c 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -893,11 +893,6 @@ typedef struct { void *selected_ocsp_func_ptr; - /* is 0 if we are to send the whole PGP key, or non zero - * if the fingerprint is to be sent. - */ - bool pgp_fingerprint; - /* This holds the default version that our first * record packet will have. */ uint8_t default_record_version[2]; @@ -915,11 +910,6 @@ typedef struct { */ bool direction; - /* This callback will be used (if set) to receive an - * openpgp key. (if the peer sends a fingerprint) - */ - gnutls_openpgp_recv_key_func openpgp_recv_key_func; - /* If non zero the server will not advertise the CA's he * trusts (do not send an RDN sequence). */ @@ -153,31 +153,6 @@ _gnutls_mpi_init_scan_nz(bigint_t * ret_mpi, const void *buffer, size_t nbytes) return 0; } -#ifdef ENABLE_OPENPGP -int -_gnutls_mpi_init_scan_pgp(bigint_t * ret_mpi, const void *buffer, size_t nbytes) -{ -bigint_t r; -int ret; - - ret = _gnutls_mpi_init(&r); - if (ret < 0) - return gnutls_assert_val(ret); - - ret = - _gnutls_mpi_scan_pgp(r, buffer, nbytes); - if (ret < 0) { - gnutls_assert(); - _gnutls_mpi_release(&r); - return ret; - } - - *ret_mpi = r; - - return 0; -} -#endif - /* Always has the first bit zero */ int _gnutls_mpi_dprint_lz(const bigint_t a, gnutls_datum_t * dest) { @@ -75,13 +75,6 @@ int _gnutls_mpi_init_scan(bigint_t * ret_mpi, const void *buffer, int _gnutls_mpi_init_scan_nz(bigint_t * ret_mpi, const void *buffer, size_t nbytes); -#ifdef ENABLE_OPENPGP -#define _gnutls_mpi_print_pgp(x,y,z) _gnutls_mpi_ops.bigint_print(x,y,z,GNUTLS_MPI_FORMAT_PGP) -#define _gnutls_mpi_scan_pgp(r, b, s) _gnutls_mpi_ops.bigint_scan(r, b, s, GNUTLS_MPI_FORMAT_PGP) -int _gnutls_mpi_init_scan_pgp(bigint_t * ret_mpi, const void *buffer, - size_t nbytes); -#endif - int _gnutls_mpi_dprint_lz(const bigint_t a, gnutls_datum_t * dest); int _gnutls_mpi_dprint(const bigint_t a, gnutls_datum_t * dest); int _gnutls_mpi_dprint_size(const bigint_t a, gnutls_datum_t * dest, diff --git a/lib/nettle/mpi.c b/lib/nettle/mpi.c index 24df1583fa..c45aa3e0ae 100644 --- a/lib/nettle/mpi.c +++ b/lib/nettle/mpi.c @@ -43,10 +43,6 @@ wrap_nettle_mpi_print(const bigint_t a, void *buffer, size_t * nbytes, size = nettle_mpz_sizeinbase_256_u(*p); } else if (format == GNUTLS_MPI_FORMAT_STD) { size = nettle_mpz_sizeinbase_256_s(*p); -#ifdef ENABLE_OPENPGP - } else if (format == GNUTLS_MPI_FORMAT_PGP) { - size = nettle_mpz_sizeinbase_256_u(*p) + 2; -#endif } else { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; @@ -57,18 +53,8 @@ wrap_nettle_mpi_print(const bigint_t a, void *buffer, size_t * nbytes, return GNUTLS_E_SHORT_MEMORY_BUFFER; } -#ifdef ENABLE_OPENPGP - if (format == GNUTLS_MPI_FORMAT_PGP) { - uint8_t *buf = buffer; - unsigned int nbits = _gnutls_mpi_get_nbits(a); - buf[0] = (nbits >> 8) & 0xff; - buf[1] = (nbits) & 0xff; - nettle_mpz_get_str_256(size - 2, buf + 2, *p); - } else -#endif - { - nettle_mpz_get_str_256(size, buffer, *p); - } + nettle_mpz_get_str_256(size, buffer, *p); + *nbytes = size; return 0; @@ -150,25 +136,6 @@ wrap_nettle_mpi_scan(bigint_t r, const void *buffer, size_t nbytes, nettle_mpz_set_str_256_u(TOMPZ(r), nbytes, buffer); } else if (format == GNUTLS_MPI_FORMAT_STD) { nettle_mpz_set_str_256_s(TOMPZ(r), nbytes, buffer); -#ifdef ENABLE_OPENPGP - } else if (format == GNUTLS_MPI_FORMAT_PGP) { - const uint8_t *buf = buffer; - size_t size; - - if (nbytes < 3) { - gnutls_assert(); - goto fail; - } - - size = (buf[0] << 8) | buf[1]; - size = (size + 7) / 8; - - if (size > nbytes - 2) { - gnutls_assert(); - goto fail; - } - nettle_mpz_set_str_256_u(TOMPZ(r), size, buf + 2); -#endif } else { gnutls_assert(); goto fail; diff --git a/lib/opencdk/Makefile.am b/lib/opencdk/Makefile.am deleted file mode 100644 index 1503234952..0000000000 --- a/lib/opencdk/Makefile.am +++ /dev/null @@ -1,42 +0,0 @@ -## Process this file with automake to produce Makefile.in -# Copyright (C) 2004-2012 Free Software Foundation, Inc. -# -# Author: Nikos Mavroyanopoulos -# -# This file is part of GnuTLS. -# -# The GnuTLS 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 3 of -# the License, or (at your option) any later version. -# -# The GnuTLS 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 program. If not, see <http://www.gnu.org/licenses/> - -include $(top_srcdir)/lib/common.mk - -AM_CPPFLAGS = \ - -I$(srcdir)/../../gl \ - -I$(builddir)/../../gl \ - -I$(srcdir)/../includes \ - -I$(builddir)/../includes \ - -I$(builddir)/../../gl \ - -I$(srcdir)/.. - -if ENABLE_MINITASN1 -AM_CPPFLAGS += -I$(srcdir)/../minitasn1 -endif - -noinst_LTLIBRARIES = libminiopencdk.la - -libminiopencdk_la_SOURCES = armor.c filters.h keydb.h types.h \ - kbnode.c main.h packet.h sig-check.c \ - keydb.c pubkey.c stream.c write-packet.c misc.c seskey.c \ - context.h literal.c new-packet.c read-packet.c stream.h opencdk.h - -EXTRA_DIST = README diff --git a/lib/opencdk/README b/lib/opencdk/README deleted file mode 100644 index 2cf780e04c..0000000000 --- a/lib/opencdk/README +++ /dev/null @@ -1,5 +0,0 @@ -This is a stripped down mirror of the files in OpenCDK -src/. To avoid to link proc-packets.c, dummy.c is included. - -In Makefile.am libminiopencdk_la_SOURCES contains the list -of all needed files. diff --git a/lib/opencdk/armor.c b/lib/opencdk/armor.c deleted file mode 100644 index e2c945b5f1..0000000000 --- a/lib/opencdk/armor.c +++ /dev/null @@ -1,495 +0,0 @@ -/* armor.c - Armor filters - * Copyright (C) 1998-2012 Free Software Foundation, Inc. - * - * Author: Timo Schulz - * - * This file is part of OpenCDK. - * - * The OpenCDK 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include <string.h> -#include <sys/stat.h> -#include <nettle/base64.h> - -#include "opencdk.h" -#include "main.h" -#include "filters.h" - -#ifdef _WIN32 -#define LF "\r\n" -#define ALTLF "\n" -#else -#define LF "\n" -#define ALTLF "\r\n" -#endif - -#define CRCINIT 0xB704CE - -static const u32 crc_table[] = { - 0x000000, 0x864CFB, 0x8AD50D, 0x0C99F6, 0x93E6E1, 0x15AA1A, - 0x1933EC, 0x9F7F17, 0xA18139, 0x27CDC2, 0x2B5434, 0xAD18CF, - 0x3267D8, 0xB42B23, 0xB8B2D5, 0x3EFE2E, 0xC54E89, 0x430272, - 0x4F9B84, 0xC9D77F, 0x56A868, 0xD0E493, 0xDC7D65, 0x5A319E, - 0x64CFB0, 0xE2834B, 0xEE1ABD, 0x685646, 0xF72951, 0x7165AA, - 0x7DFC5C, 0xFBB0A7, 0x0CD1E9, 0x8A9D12, 0x8604E4, 0x00481F, - 0x9F3708, 0x197BF3, 0x15E205, 0x93AEFE, 0xAD50D0, 0x2B1C2B, - 0x2785DD, 0xA1C926, 0x3EB631, 0xB8FACA, 0xB4633C, 0x322FC7, - 0xC99F60, 0x4FD39B, 0x434A6D, 0xC50696, 0x5A7981, 0xDC357A, - 0xD0AC8C, 0x56E077, 0x681E59, 0xEE52A2, 0xE2CB54, 0x6487AF, - 0xFBF8B8, 0x7DB443, 0x712DB5, 0xF7614E, 0x19A3D2, 0x9FEF29, - 0x9376DF, 0x153A24, 0x8A4533, 0x0C09C8, 0x00903E, 0x86DCC5, - 0xB822EB, 0x3E6E10, 0x32F7E6, 0xB4BB1D, 0x2BC40A, 0xAD88F1, - 0xA11107, 0x275DFC, 0xDCED5B, 0x5AA1A0, 0x563856, 0xD074AD, - 0x4F0BBA, 0xC94741, 0xC5DEB7, 0x43924C, 0x7D6C62, 0xFB2099, - 0xF7B96F, 0x71F594, 0xEE8A83, 0x68C678, 0x645F8E, 0xE21375, - 0x15723B, 0x933EC0, 0x9FA736, 0x19EBCD, 0x8694DA, 0x00D821, - 0x0C41D7, 0x8A0D2C, 0xB4F302, 0x32BFF9, 0x3E260F, 0xB86AF4, - 0x2715E3, 0xA15918, 0xADC0EE, 0x2B8C15, 0xD03CB2, 0x567049, - 0x5AE9BF, 0xDCA544, 0x43DA53, 0xC596A8, 0xC90F5E, 0x4F43A5, - 0x71BD8B, 0xF7F170, 0xFB6886, 0x7D247D, 0xE25B6A, 0x641791, - 0x688E67, 0xEEC29C, 0x3347A4, 0xB50B5F, 0xB992A9, 0x3FDE52, - 0xA0A145, 0x26EDBE, 0x2A7448, 0xAC38B3, 0x92C69D, 0x148A66, - 0x181390, 0x9E5F6B, 0x01207C, 0x876C87, 0x8BF571, 0x0DB98A, - 0xF6092D, 0x7045D6, 0x7CDC20, 0xFA90DB, 0x65EFCC, 0xE3A337, - 0xEF3AC1, 0x69763A, 0x578814, 0xD1C4EF, 0xDD5D19, 0x5B11E2, - 0xC46EF5, 0x42220E, 0x4EBBF8, 0xC8F703, 0x3F964D, 0xB9DAB6, - 0xB54340, 0x330FBB, 0xAC70AC, 0x2A3C57, 0x26A5A1, 0xA0E95A, - 0x9E1774, 0x185B8F, 0x14C279, 0x928E82, 0x0DF195, 0x8BBD6E, - 0x872498, 0x016863, 0xFAD8C4, 0x7C943F, 0x700DC9, 0xF64132, - 0x693E25, 0xEF72DE, 0xE3EB28, 0x65A7D3, 0x5B59FD, 0xDD1506, - 0xD18CF0, 0x57C00B, 0xC8BF1C, 0x4EF3E7, 0x426A11, 0xC426EA, - 0x2AE476, 0xACA88D, 0xA0317B, 0x267D80, 0xB90297, 0x3F4E6C, - 0x33D79A, 0xB59B61, 0x8B654F, 0x0D29B4, 0x01B042, 0x87FCB9, - 0x1883AE, 0x9ECF55, 0x9256A3, 0x141A58, 0xEFAAFF, 0x69E604, - 0x657FF2, 0xE33309, 0x7C4C1E, 0xFA00E5, 0xF69913, 0x70D5E8, - 0x4E2BC6, 0xC8673D, 0xC4FECB, 0x42B230, 0xDDCD27, 0x5B81DC, - 0x57182A, 0xD154D1, 0x26359F, 0xA07964, 0xACE092, 0x2AAC69, - 0xB5D37E, 0x339F85, 0x3F0673, 0xB94A88, 0x87B4A6, 0x01F85D, - 0x0D61AB, 0x8B2D50, 0x145247, 0x921EBC, 0x9E874A, 0x18CBB1, - 0xE37B16, 0x6537ED, 0x69AE1B, 0xEFE2E0, 0x709DF7, 0xF6D10C, - 0xFA48FA, 0x7C0401, 0x42FA2F, 0xC4B6D4, 0xC82F22, 0x4E63D9, - 0xD11CCE, 0x575035, 0x5BC9C3, 0xDD8538 -}; - -static const char *armor_begin[] = { - "BEGIN PGP MESSAGE", - "BEGIN PGP PUBLIC KEY BLOCK", - "BEGIN PGP PRIVATE KEY BLOCK", - "BEGIN PGP SIGNATURE", - NULL -}; - -static const char *armor_end[] = { - "END PGP MESSAGE", - "END PGP PUBLIC KEY BLOCK", - "END PGP PRIVATE KEY BLOCK", - "END PGP SIGNATURE", - NULL -}; - -static const char *valid_headers[] = { - "Comment", - "Version", - "MessageID", - "Hash", - "Charset", - NULL -}; - -static char b64chars[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -static u32 update_crc(u32 crc, const byte * buf, size_t buflen) -{ - unsigned int j; - - if (!crc) - crc = CRCINIT; - - for (j = 0; j < buflen; j++) - crc = - (crc << 8) ^ crc_table[0xff & ((crc >> 16) ^ buf[j])]; - crc &= 0xffffff; - return crc; -} - - -static cdk_error_t armor_encode(void *data, FILE * in, FILE * out) -{ - armor_filter_t *afx = data; - struct stat statbuf; - char crcbuf[5], buf[128], raw[49]; - byte crcbuf2[3]; - size_t nread = 0; - const char *lf; - - if (!afx) { - gnutls_assert(); - return CDK_Inv_Value; - } - if (afx->idx < 0 || afx->idx >= (int) DIM(armor_begin) || - afx->idx2 < 0 || afx->idx2 >= (int) DIM(armor_end)) { - gnutls_assert(); - return CDK_Inv_Value; - } - - _gnutls_buffers_log("armor filter: encode\n"); - - memset(crcbuf, 0, sizeof(crcbuf)); - - lf = afx->le ? afx->le : LF; - fprintf(out, "-----%s-----%s", armor_begin[afx->idx], lf); - fprintf(out, "Version: OpenPrivacy " PACKAGE_VERSION "%s", lf); - if (afx->hdrlines) - fwrite(afx->hdrlines, 1, strlen(afx->hdrlines), out); - fprintf(out, "%s", lf); - - if (fstat(fileno(in), &statbuf)) { - gnutls_assert(); - return CDK_General_Error; - } - - while (!feof(in)) { - nread = fread(raw, 1, DIM(raw) - 1, in); - if (!nread) - break; - if (ferror(in)) { - gnutls_assert(); - return CDK_File_Error; - } - afx->crc = update_crc(afx->crc, (byte *) raw, nread); - if (DIM(buf)-1 < BASE64_ENCODE_RAW_LENGTH(nread)) { - gnutls_assert(); - return CDK_File_Error; - } - - base64_encode_raw((uint8_t*)buf, nread, (uint8_t*)raw); - buf[BASE64_ENCODE_RAW_LENGTH(nread)] = 0; - fprintf(out, "%s%s", buf, lf); - } - - crcbuf2[0] = afx->crc >> 16; - crcbuf2[1] = afx->crc >> 8; - crcbuf2[2] = afx->crc; - crcbuf[0] = b64chars[crcbuf2[0] >> 2]; - crcbuf[1] = - b64chars[((crcbuf2[0] << 4) & 0x30) | (crcbuf2[1] >> 4)]; - crcbuf[2] = - b64chars[((crcbuf2[1] << 2) & 0x3c) | (crcbuf2[2] >> 6)]; - crcbuf[3] = b64chars[crcbuf2[2] & 0x3f]; - fprintf(out, "=%s%s", crcbuf, lf); - fprintf(out, "-----%s-----%s", armor_end[afx->idx2], lf); - - return 0; -} - -static int search_header(const char *buf, const char **array) -{ - const char *s; - int i; - - if (strlen(buf) < 5 || strncmp(buf, "-----", 5)) { - return -1; - } - for (i = 0; (s = array[i]); i++) { - if (!strncmp(s, buf + 5, strlen(s))) - return i; - } - return -1; -} - -static cdk_error_t armor_decode(void *data, FILE * in, FILE * out) -{ - armor_filter_t *afx = data; - const char *s; - char buf[127]; - byte raw[128], crcbuf[4]; - u32 crc2 = 0; - int i, pgp_data = 0, ret; - cdk_error_t rc = 0; - int len; - size_t raw_size, crcbuf_size; - struct base64_decode_ctx ctx; - - if (!afx) { - gnutls_assert(); - return CDK_Inv_Value; - } - - _gnutls_buffers_log("armor filter: decode\n"); - - fseek(in, 0, SEEK_SET); - /* Search the begin of the message */ - while (!feof(in) && !pgp_data) { - s = fgets(buf, DIM(buf) - 1, in); - if (!s) - break; - afx->idx = search_header(buf, armor_begin); - if (afx->idx >= 0) - pgp_data = 1; - } - - if (feof(in) || !pgp_data) { - return CDK_Armor_Error; /* no data found */ - } - - /* Parse header until the empty line is reached */ - while (!feof(in)) { - s = fgets(buf, DIM(buf) - 1, in); - if (!s) - return CDK_EOF; - if (strcmp(s, LF) == 0 || strcmp(s, ALTLF) == 0) { - rc = 0; - break; /* empty line */ - } - /* From RFC2440: OpenPGP should consider improperly formatted Armor - Headers to be corruption of the ASCII Armor. A colon and a single - space separate the key and value. */ - if (!strstr(buf, ": ")) { - gnutls_assert(); - return CDK_Armor_Error; - } - rc = CDK_General_Error; - for (i = 0; (s = valid_headers[i]); i++) { - if (!strncmp(s, buf, strlen(s))) - rc = 0; - } - if (rc) { - /* From RFC2440: Unknown keys should be reported to the user, - but OpenPGP should continue to process the message. */ - _cdk_log_info("unknown header: `%s'\n", buf); - rc = 0; - } - } - - /* Read the data body */ - while (!feof(in)) { - s = fgets(buf, DIM(buf) - 1, in); - if (!s) - break; - - len = strlen(buf); - - if (len > 0 && buf[len - 1] == '\n') { - len--; - buf[len] = '\0'; - } - if (len > 0 && buf[len - 1] == '\r') { - len--; - buf[len] = '\0'; - } - if (buf[0] == '=' && strlen(s) == 5) { /* CRC */ - base64_decode_init(&ctx); - - memset(crcbuf, 0, sizeof(crcbuf)); - crcbuf_size = sizeof(crcbuf); - if ((ssize_t)crcbuf_size < BASE64_DECODE_LENGTH(len-1)) - return gnutls_assert_val(GNUTLS_E_BASE64_DECODING_ERROR); - - ret = base64_decode_update(&ctx, &crcbuf_size, crcbuf, - len-1, (uint8_t*)buf+1); - if (ret == 0) - return gnutls_assert_val(GNUTLS_E_BASE64_DECODING_ERROR); - - ret = base64_decode_final(&ctx); - if (ret != 1) - return gnutls_assert_val(GNUTLS_E_BASE64_DECODING_ERROR); - - crc2 = - (crcbuf[0] << 16) | (crcbuf[1] << 8) | - crcbuf[2]; - break; /* stop here */ - } else { - base64_decode_init(&ctx); - - raw_size = sizeof(raw); - if ((ssize_t)raw_size < BASE64_DECODE_LENGTH(len)) - return gnutls_assert_val(GNUTLS_E_BASE64_DECODING_ERROR); - ret = base64_decode_update(&ctx, &raw_size, raw, - len, (uint8_t*)buf); - if (ret == 0) - return gnutls_assert_val(GNUTLS_E_BASE64_DECODING_ERROR); - - ret = base64_decode_final(&ctx); - if (ret != 1) - return gnutls_assert_val(GNUTLS_E_BASE64_DECODING_ERROR); - - afx->crc = update_crc(afx->crc, raw, raw_size); - fwrite(raw, 1, raw_size, out); - } - } - - /* Search the tail of the message */ - s = fgets(buf, DIM(buf) - 1, in); - if (s) { - int buf_len = strlen(buf); - if (buf[buf_len - 1] == '\n') { - buf_len--; - buf[buf_len] = '\0'; - } - if (buf[buf_len - 1] == '\r') { - buf_len--; - buf[buf_len] = '\0'; - } - rc = CDK_General_Error; - afx->idx2 = search_header(buf, armor_end); - if (afx->idx2 >= 0) - rc = 0; - } - - /* This catches error when no tail was found or the header is - different then the tail line. */ - if (rc || afx->idx != afx->idx2) - rc = CDK_Armor_Error; - - afx->crc_okay = (afx->crc == crc2) ? 1 : 0; - if (!afx->crc_okay && !rc) { - _gnutls_buffers_log("file crc=%08X afx_crc=%08X\n", - (unsigned int) crc2, - (unsigned int) afx->crc); - rc = CDK_Armor_CRC_Error; - } - - return rc; -} - -int _cdk_filter_armor(void *data, int ctl, FILE * in, FILE * out) -{ - if (ctl == STREAMCTL_READ) - return armor_decode(data, in, out); - else if (ctl == STREAMCTL_WRITE) - return armor_encode(data, in, out); - else if (ctl == STREAMCTL_FREE) { - armor_filter_t *afx = data; - if (afx) { - _gnutls_buffers_log("free armor filter\n"); - afx->idx = afx->idx2 = 0; - afx->crc = afx->crc_okay = 0; - return 0; - } - } - - gnutls_assert(); - return CDK_Inv_Mode; -} - - -/** - * cdk_armor_encode_buffer: - * @inbuf: the raw input buffer - * @inlen: raw buffer len - * @outbuf: the destination buffer for the base64 output - * @outlen: destination buffer len - * @nwritten: actual length of the base64 data - * @type: the base64 file type. - * - * Encode the given buffer into base64 format. The base64 - * string will be null terminated but the null will - * not be contained in the size. - **/ -cdk_error_t -cdk_armor_encode_buffer(const byte * inbuf, size_t inlen, - char *outbuf, size_t outlen, - size_t * nwritten, int type) -{ - const char *head, *tail, *le; - char tempbuf[48]; - char tempout[128]; - size_t pos, off, len, rest; - - if (!inbuf || !nwritten) { - gnutls_assert(); - return CDK_Inv_Value; - } - if (type > CDK_ARMOR_SIGNATURE) { - gnutls_assert(); - return CDK_Inv_Mode; - } - - head = armor_begin[type]; - tail = armor_end[type]; - le = LF; - pos = - strlen(head) + 10 + 2 + 2 + strlen(tail) + 10 + 2 + 5 + 2 + 1; - /* The output data is 4/3 times larger, plus a line end for each line. */ - pos += (4 * inlen / 3) + 2 * (4 * inlen / 3 / 64) + 1; - - if (outbuf && outlen < pos) { - gnutls_assert(); - *nwritten = pos; - return CDK_Too_Short; - } - - /* Only return the size of the output. */ - if (!outbuf) { - *nwritten = pos; - return 0; - } - - memset(outbuf, 0, outlen); - memcpy(outbuf, "-----", 5); - pos = 5; - memcpy(outbuf + pos, head, strlen(head)); - pos += strlen(head); - memcpy(outbuf + pos, "-----", 5); - pos += 5; - memcpy(outbuf + pos, le, strlen(le)); - pos += strlen(le); - memcpy(outbuf + pos, le, strlen(le)); - pos += strlen(le); - rest = inlen; - for (off = 0; off < inlen;) { - if (rest > 48) { - memcpy(tempbuf, inbuf + off, 48); - off += 48; - len = 48; - } else { - memcpy(tempbuf, inbuf + off, rest); - off += rest; - len = rest; - } - rest -= len; - - if (DIM(tempout)-1 < BASE64_ENCODE_RAW_LENGTH(len)) { - gnutls_assert(); - return CDK_File_Error; - } - - base64_encode_raw((uint8_t*)tempout, len, (uint8_t*)tempbuf); - tempout[BASE64_ENCODE_RAW_LENGTH(len)] = 0; - - memcpy(outbuf + pos, tempout, strlen(tempout)); - pos += strlen(tempout); - memcpy(outbuf + pos, le, strlen(le)); - pos += strlen(le); - } - - memcpy(outbuf + pos, "-----", 5); - pos += 5; - memcpy(outbuf + pos, tail, strlen(tail)); - pos += strlen(tail); - memcpy(outbuf + pos, "-----", 5); - pos += 5; - memcpy(outbuf + pos, le, strlen(le)); - pos += strlen(le); - outbuf[pos] = 0; - *nwritten = pos - 1; - return 0; -} diff --git a/lib/opencdk/context.h b/lib/opencdk/context.h deleted file mode 100644 index ba17d24d29..0000000000 --- a/lib/opencdk/context.h +++ /dev/null @@ -1,123 +0,0 @@ -/* context.h - * Copyright (C) 2002-2012 Free Software Foundation, Inc. - * - * Author: Timo Schulz - * - * This file is part of OpenCDK. - * - * The OpenCDK 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef CDK_CONTEXT_H -#define CDK_CONTEXT_H - -#include "types.h" - -struct cdk_listkey_s { - unsigned init:1; - cdk_stream_t inp; - cdk_keydb_hd_t db; - int type; - union { - char *patt; - cdk_strlist_t fpatt; - } u; - cdk_strlist_t t; -}; - - -struct cdk_s2k_s { - int mode; - byte hash_algo; - byte salt[8]; - u32 count; -}; - - -struct cdk_ctx_s { - int cipher_algo; - int digest_algo; - struct { - int algo; - int level; - } compress; - struct { - int mode; - int digest_algo; - } _s2k; - struct { - unsigned blockmode:1; - unsigned armor:1; - unsigned textmode:1; - unsigned compress:1; - unsigned mdc:1; - unsigned overwrite; - unsigned force_digest:1; - } opt; - struct { - cdk_pkt_seckey_t sk; - unsigned on:1; - } cache; - struct { - cdk_keydb_hd_t sec; - cdk_keydb_hd_t pub; - unsigned int close_db:1; - } db; - char *(*passphrase_cb) (void *uint8_t, const char *prompt); - void *passphrase_cb_value; -}; - -struct cdk_prefitem_s { - byte type; - byte value; -}; - -struct cdk_desig_revoker_s { - struct cdk_desig_revoker_s *next; - byte r_class; - byte algid; - byte fpr[KEY_FPR_LEN]; -}; - -struct cdk_subpkt_s { - struct cdk_subpkt_s *next; - u32 size; - byte type; - byte *d; -}; - -struct cdk_keylist_s { - struct cdk_keylist_s *next; - union { - cdk_pkt_pubkey_t pk; - cdk_pkt_seckey_t sk; - } key; - int version; - int type; -}; - -struct cdk_dek_s { - int algo; - int keylen; - int use_mdc; - byte key[32]; /* 256-bit */ -}; - -struct cdk_strlist_s { - struct cdk_strlist_s *next; - char *d; -}; - -#endif /* CDK_CONTEXT_H */ diff --git a/lib/opencdk/filters.h b/lib/opencdk/filters.h deleted file mode 100644 index e5a96d54ad..0000000000 --- a/lib/opencdk/filters.h +++ /dev/null @@ -1,102 +0,0 @@ -/* filters.h - Filter structs - * Copyright (C) 2002-2012 Free Software Foundation, Inc. - * - * Author: Timo Schulz - * - * This file is part of OpenCDK. - * - * The OpenCDK 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef CDK_FILTERS_H -#define CDK_FILTERS_H - -enum { - STREAMCTL_READ = 0, - STREAMCTL_WRITE = 1, - STREAMCTL_FREE = 2 -}; - -typedef struct { - cipher_hd_st hd; - digest_hd_st mdc; - int mdc_method; - u32 datalen; - struct { - size_t on; - off_t size; - off_t nleft; - } blkmode; - cdk_stream_t s; -} cipher_filter_t; - -typedef struct { - int digest_algo; - digest_hd_st md; - int md_initialized; -} md_filter_t; - -typedef struct { - const char *le; /* line endings */ - const char *hdrlines; - u32 crc; - int crc_okay; - int idx, idx2; -} armor_filter_t; - -typedef struct { - cdk_lit_format_t mode; - char *orig_filename; /* This original name of the input file. */ - char *filename; - digest_hd_st md; - int md_initialized; - struct { - size_t on; - off_t size; - } blkmode; -} literal_filter_t; - -typedef struct { - size_t inbufsize; - byte inbuf[8192]; - size_t outbufsize; - byte outbuf[8192]; - int algo; /* compress algo */ - int level; -} compress_filter_t; - -typedef struct { - const char *lf; -} text_filter_t; - - -/*-- armor.c -*/ -int _cdk_filter_armor(void *uint8_t, int ctl, FILE * in, FILE * out); - -/*-- cipher.c --*/ -cdk_error_t _cdk_filter_hash(void *uint8_t, int ctl, FILE * in, - FILE * out); -cdk_error_t _cdk_filter_cipher(void *uint8_t, int ctl, FILE * in, - FILE * out); - -/*-- literal.c --*/ -int _cdk_filter_literal(void *uint8_t, int ctl, FILE * in, FILE * out); -int _cdk_filter_text(void *uint8_t, int ctl, FILE * in, FILE * out); - -/*-- compress.c --*/ -cdk_error_t _cdk_filter_compress(void *uint8_t, int ctl, - FILE * in, FILE * out); - -#endif /* CDK_FILTERS_H */ diff --git a/lib/opencdk/kbnode.c b/lib/opencdk/kbnode.c deleted file mode 100644 index cad9beb882..0000000000 --- a/lib/opencdk/kbnode.c +++ /dev/null @@ -1,593 +0,0 @@ -/* kbnode.c - keyblock node utility functions - * Copyright (C) 1998-2012 Free Software Foundation, Inc. - * - * Author: Timo Schulz - * - * This file is part of OpenCDK. - * - * The OpenCDK 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "opencdk.h" -#include "main.h" -#include "packet.h" - - -/** - * cdk_kbnode_new: - * @pkt: the packet to add - * - * Allocates a new key node and adds a packet. - **/ -cdk_kbnode_t cdk_kbnode_new(cdk_packet_t pkt) -{ - cdk_kbnode_t n; - - n = cdk_calloc(1, sizeof *n); - if (!n) - return NULL; - n->pkt = pkt; - return n; -} - - -void _cdk_kbnode_clone(cdk_kbnode_t node) -{ - /* Mark the node as clone which means that the packet - will not be freed, just the node itself. */ - if (node) - node->is_cloned = 1; -} - - -/** - * cdk_kbnode_release: - * @n: the key node - * - * Releases the memory of the node. - **/ -void cdk_kbnode_release(cdk_kbnode_t node) -{ - cdk_kbnode_t n2; - - while (node) { - n2 = node->next; - if (!node->is_cloned) - cdk_pkt_release(node->pkt); - cdk_free(node); - node = n2; - } -} - - -/** - * cdk_kbnode_delete: - * @node: the key node - * - * Marks the given node as deleted. - **/ -void cdk_kbnode_delete(cdk_kbnode_t node) -{ - if (node) - node->is_deleted = 1; -} - - -/* Append NODE to ROOT. ROOT must exist! */ -void _cdk_kbnode_add(cdk_kbnode_t root, cdk_kbnode_t node) -{ - cdk_kbnode_t n1; - - for (n1 = root; n1->next; n1 = n1->next); - n1->next = node; -} - - -/** - * cdk_kbnode_insert: - * @root: the root key node - * @node: the node to add - * @pkttype: packet type - * - * Inserts @node into the list after @root but before a packet which is not of - * type @pkttype (only if @pkttype != 0). - **/ -void -cdk_kbnode_insert(cdk_kbnode_t root, cdk_kbnode_t node, - cdk_packet_type_t pkttype) -{ - if (!pkttype) { - node->next = root->next; - root->next = node; - } else { - cdk_kbnode_t n1; - - for (n1 = root; n1->next; n1 = n1->next) - if (pkttype != n1->next->pkt->pkttype) { - node->next = n1->next; - n1->next = node; - return; - } - /* No such packet, append */ - node->next = NULL; - n1->next = node; - } -} - - -/** - * cdk_kbnode_find_prev: - * @root: the root key node - * @node: the key node - * @pkttype: packet type - * - * Finds the previous node (if @pkttype = 0) or the previous node - * with pkttype @pkttype in the list starting with @root of @node. - **/ -cdk_kbnode_t -cdk_kbnode_find_prev(cdk_kbnode_t root, cdk_kbnode_t node, - cdk_packet_type_t pkttype) -{ - cdk_kbnode_t n1; - - for (n1 = NULL; root && root != node; root = root->next) { - if (!pkttype || root->pkt->pkttype == pkttype) - n1 = root; - } - return n1; -} - - -/** - * cdk_kbnode_find_next: - * @node: the key node - * @pkttype: packet type - * - * Ditto, but find the next packet. The behaviour is trivial if - * @pkttype is 0 but if it is specified, the next node with a packet - * of this type is returned. The function has some knowledge about - * the valid ordering of packets: e.g. if the next signature packet - * is requested, the function will not return one if it encounters - * a user-id. - **/ -cdk_kbnode_t -cdk_kbnode_find_next(cdk_kbnode_t node, cdk_packet_type_t pkttype) -{ - for (node = node->next; node; node = node->next) { - if (!pkttype) - return node; - else if (pkttype == CDK_PKT_USER_ID && - (node->pkt->pkttype == CDK_PKT_PUBLIC_KEY || - node->pkt->pkttype == CDK_PKT_SECRET_KEY)) - return NULL; - else if (pkttype == CDK_PKT_SIGNATURE && - (node->pkt->pkttype == CDK_PKT_USER_ID || - node->pkt->pkttype == CDK_PKT_PUBLIC_KEY || - node->pkt->pkttype == CDK_PKT_SECRET_KEY)) - return NULL; - else if (node->pkt->pkttype == pkttype) - return node; - } - return NULL; -} - - -/** - * cdk_kbnode_find: - * @node: the key node - * @pkttype: packet type - * - * Tries to find the next node with the packettype @pkttype. - **/ -cdk_kbnode_t cdk_kbnode_find(cdk_kbnode_t node, cdk_packet_type_t pkttype) -{ - for (; node; node = node->next) { - if (node->pkt->pkttype == pkttype) - return node; - } - return NULL; -} - - -/** - * cdk_kbnode_find_packet: - * @node: the key node - * @pkttype: packet type - * - * Same as cdk_kbnode_find but it returns the packet instead of the node. - **/ -cdk_packet_t -cdk_kbnode_find_packet(cdk_kbnode_t node, cdk_packet_type_t pkttype) -{ - cdk_kbnode_t res; - - res = cdk_kbnode_find(node, pkttype); - return res ? res->pkt : NULL; -} - - -/** - * cdk_kbnode_walk: - * - * Walks through a list of kbnodes. This function returns - * the next kbnode for each call; before using the function the first - * time, the caller must set CONTEXT to NULL (This has simply the effect - * to start with ROOT). - */ -cdk_kbnode_t -cdk_kbnode_walk(cdk_kbnode_t root, cdk_kbnode_t * ctx, int all) -{ - cdk_kbnode_t n; - - do { - if (!*ctx) { - *ctx = root; - n = root; - } else { - n = (*ctx)->next; - *ctx = n; - } - } - while (!all && n && n->is_deleted); - return n; -} - - -/** - * cdk_kbnode_commit: - * @root: the nodes - * - * Commits changes made to the kblist at ROOT. Note that ROOT my change, - * and it is therefore passed by reference. - * The function has the effect of removing all nodes marked as deleted. - * - * Returns: true if any node has been changed - */ -int cdk_kbnode_commit(cdk_kbnode_t * root) -{ - cdk_kbnode_t n, nl; - int changed = 0; - - for (n = *root, nl = NULL; n; n = nl->next) { - if (n->is_deleted) { - if (n == *root) - *root = nl = n->next; - else - nl->next = n->next; - if (!n->is_cloned) - cdk_pkt_release(n->pkt); - cdk_free(n); - changed = 1; - } else - nl = n; - } - return changed; -} - - -/** - * cdk_kbnode_remove: - * @root: the root node - * @node: the node to delete - * - * Removes a node from the root node. - */ -void cdk_kbnode_remove(cdk_kbnode_t * root, cdk_kbnode_t node) -{ - cdk_kbnode_t n, nl; - - for (n = *root, nl = NULL; n; n = nl->next) { - if (n == node) { - if (n == *root) - *root = nl = n->next; - else - nl->next = n->next; - if (!n->is_cloned) - cdk_pkt_release(n->pkt); - cdk_free(n); - } else - nl = n; - } -} - - - -/** - * cdk_cdknode_move: - * @root: root node - * @node: the node to move - * @where: destination place where to move the node. - * - * Moves NODE behind right after WHERE or to the beginning if WHERE is NULL. - */ -void -cdk_kbnode_move(cdk_kbnode_t * root, cdk_kbnode_t node, cdk_kbnode_t where) -{ - cdk_kbnode_t tmp, prev; - - if (!root || !*root || !node) - return; - for (prev = *root; prev && prev->next != node; prev = prev->next); - if (!prev) - return; /* Node is not in the list */ - - if (!where) { /* Move node before root */ - if (node == *root) - return; - prev->next = node->next; - node->next = *root; - *root = node; - return; - } - if (node == where) /* Move it after where. */ - return; - tmp = node->next; - node->next = where->next; - where->next = node; - prev->next = tmp; -} - - -/** - * cdk_kbnode_get_packet: - * @node: the key node - * - * Get packet in node. - * - * Returns: the packet which is stored inside the node in @node. - **/ -cdk_packet_t cdk_kbnode_get_packet(cdk_kbnode_t node) -{ - if (node) - return node->pkt; - return NULL; -} - - -/** - * cdk_kbnode_read_from_mem: - * @ret_node: the new key node - * @armor: whether base64 or not - * @buf: the buffer which stores the key sequence - * @buflen: the length of the buffer - * @public: non-zero if reading a public key - * - * Tries to read a key node from the memory buffer @buf. - **/ -cdk_error_t -cdk_kbnode_read_from_mem(cdk_kbnode_t * ret_node, - int armor, const byte * buf, size_t buflen, - unsigned public) -{ - cdk_stream_t inp; - cdk_error_t rc; - - if (!ret_node || !buf) - return CDK_Inv_Value; - - *ret_node = NULL; - if (!buflen) - return gnutls_assert_val(CDK_Too_Short); - - rc = cdk_stream_tmp_from_mem(buf, buflen, &inp); - if (rc) - return gnutls_assert_val(rc); - - if (armor) - cdk_stream_set_armor_flag(inp, 0); - - rc = cdk_keydb_get_keyblock(inp, ret_node, public); - if (rc) - gnutls_assert(); - cdk_stream_close(inp); - return rc; -} - - -/** - * cdk_kbnode_write_to_mem_alloc: - * @node: the key node - * @r_buf: buffer to hold the raw data - * @r_buflen: buffer length of the allocated raw data. - * - * The function acts similar to cdk_kbnode_write_to_mem but - * it allocates the buffer to avoid the lengthy second run. - */ -cdk_error_t -cdk_kbnode_write_to_mem_alloc(cdk_kbnode_t node, - byte ** r_buf, size_t * r_buflen) -{ - cdk_kbnode_t n; - cdk_stream_t s; - cdk_error_t rc; - ssize_t len; - - if (!node || !r_buf || !r_buflen) { - gnutls_assert(); - return CDK_Inv_Value; - } - - *r_buf = NULL; - *r_buflen = 0; - - rc = cdk_stream_tmp_new(&s); - if (rc) { - gnutls_assert(); - return rc; - } - - for (n = node; n; n = n->next) { - /* Skip all packets which cannot occur in a key composition. */ - if (n->pkt->pkttype != CDK_PKT_PUBLIC_KEY && - n->pkt->pkttype != CDK_PKT_PUBLIC_SUBKEY && - n->pkt->pkttype != CDK_PKT_SECRET_KEY && - n->pkt->pkttype != CDK_PKT_SECRET_SUBKEY && - n->pkt->pkttype != CDK_PKT_SIGNATURE && - n->pkt->pkttype != CDK_PKT_USER_ID && - n->pkt->pkttype != CDK_PKT_ATTRIBUTE) - continue; - rc = cdk_pkt_write(s, n->pkt); - if (rc) { - cdk_stream_close(s); - gnutls_assert(); - return rc; - } - } - - cdk_stream_seek(s, 0); - len = cdk_stream_get_length(s); - if (len == 0) - return gnutls_assert_val(CDK_General_Error); - - *r_buf = cdk_calloc(1, len); - *r_buflen = cdk_stream_read(s, *r_buf, len); - cdk_stream_close(s); - return 0; -} - - -/** - * cdk_kbnode_write_to_mem: - * @node: the key node - * @buf: the buffer to store the node data - * @r_nbytes: the new length of the buffer. - * - * Tries to write the contents of the key node to the buffer @buf and - * return the length of it in @r_nbytes. If buf is (0), only the - * length of the node is calculated and returned in @r_nbytes. - * Whenever it is possible, the cdk_kbnode_write_to_mem_alloc should be used. - **/ -cdk_error_t -cdk_kbnode_write_to_mem(cdk_kbnode_t node, byte * buf, size_t * r_nbytes) -{ - cdk_kbnode_t n; - cdk_stream_t s; - cdk_error_t rc; - ssize_t len; - - if (!node || !r_nbytes) { - gnutls_assert(); - return CDK_Inv_Value; - } - - rc = cdk_stream_tmp_new(&s); - if (rc) { - gnutls_assert(); - return rc; - } - - for (n = node; n; n = n->next) { - /* Skip all packets which cannot occur in a key composition. */ - if (n->pkt->pkttype != CDK_PKT_PUBLIC_KEY && - n->pkt->pkttype != CDK_PKT_PUBLIC_SUBKEY && - n->pkt->pkttype != CDK_PKT_SECRET_KEY && - n->pkt->pkttype != CDK_PKT_SECRET_SUBKEY && - n->pkt->pkttype != CDK_PKT_SIGNATURE && - n->pkt->pkttype != CDK_PKT_USER_ID && - n->pkt->pkttype != CDK_PKT_ATTRIBUTE) - continue; - rc = cdk_pkt_write(s, n->pkt); - if (rc) { - cdk_stream_close(s); - gnutls_assert(); - return rc; - } - } - - cdk_stream_seek(s, 0); - - len = cdk_stream_get_length(s); - if (len == 0) - return gnutls_assert_val(CDK_General_Error); - - if (!buf) { - *r_nbytes = len; /* Only return the length of the buffer */ - cdk_stream_close(s); - return 0; - } - if (*r_nbytes < (size_t)len) { - *r_nbytes = len; - rc = CDK_Too_Short; - } - if (!rc) - *r_nbytes = cdk_stream_read(s, buf, len); - else - gnutls_assert(); - cdk_stream_close(s); - return rc; -} - - -/** - * cdk_kbnode_hash: - * @node: the key node - * @hashctx: uint8_t pointer to the hash context - * @is_v4: OpenPGP signature (yes=1, no=0) - * @pkttype: packet type to hash (if (0) use the packet type from the node) - * @flags: flags which depend on the operation - * - * Hashes the key node contents. Two modes are supported. If the packet - * type is used (!= 0) then the function searches the first node with - * this type. Otherwise the node is seen as a single node and the type - * is extracted from it. - **/ -cdk_error_t -cdk_kbnode_hash(cdk_kbnode_t node, digest_hd_st * md, int is_v4, - cdk_packet_type_t pkttype, int flags) -{ - cdk_packet_t pkt; - - if (!node || !md) { - gnutls_assert(); - return CDK_Inv_Value; - } - if (!pkttype) { - pkt = cdk_kbnode_get_packet(node); - pkttype = pkt->pkttype; - } else { - pkt = cdk_kbnode_find_packet(node, pkttype); - if (!pkt) { - gnutls_assert(); - return CDK_Inv_Packet; - } - } - - switch (pkttype) { - case CDK_PKT_PUBLIC_KEY: - case CDK_PKT_PUBLIC_SUBKEY: - _cdk_hash_pubkey(pkt->pkt.public_key, md, flags & 1); - break; - - case CDK_PKT_USER_ID: - _cdk_hash_userid(pkt->pkt.user_id, is_v4, md); - break; - - case CDK_PKT_SIGNATURE: - _cdk_hash_sig_data(pkt->pkt.signature, md); - break; - - default: - gnutls_assert(); - return CDK_Inv_Mode; - } - return 0; -} diff --git a/lib/opencdk/keydb.c b/lib/opencdk/keydb.c deleted file mode 100644 index 00351bc8d9..0000000000 --- a/lib/opencdk/keydb.c +++ /dev/null @@ -1,2073 +0,0 @@ -/* keydb.c - Key database routines - * Copyright (C) 2002-2012 Free Software Foundation, Inc. - * - * Author: Timo Schulz - * - * This file is part of OpenCDK. - * - * The OpenCDK 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <sys/stat.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> - -#include "opencdk.h" -#include "main.h" -#include "packet.h" -#include "filters.h" -#include "stream.h" -#include "keydb.h" - -#define KEYID_CMP(a, b) ((a[0]) == (b[0]) && (a[1]) == (b[1])) - -static int classify_data(const byte * buf, size_t len); -static cdk_kbnode_t find_selfsig_node(cdk_kbnode_t key, - cdk_pkt_pubkey_t pk); - -static char *keydb_idx_mkname(const char *file) -{ - static const char *fmt = "%s.idx"; - char *fname; - size_t len = strlen(file) + strlen(fmt); - - fname = cdk_calloc(1, len + 1); - if (!fname) - return NULL; - if (snprintf(fname, len, fmt, file) <= 0) - return NULL; - return fname; -} - - -/* This functions builds an index of the keyring into a separate file - with the name keyring.ext.idx. It contains the offset of all public- - and public subkeys. The format of the file is: - -------- - 4 octets offset of the packet - 8 octets keyid - 20 octets fingerprint - -------- - We store the keyid and the fingerprint due to the fact we can't get - the keyid from a v3 fingerprint directly. -*/ -static cdk_error_t keydb_idx_build(const char *file) -{ - cdk_packet_t pkt; - cdk_stream_t inp, out = NULL; - byte buf[4 + 8 + KEY_FPR_LEN]; - char *idx_name; - u32 keyid[2]; - cdk_error_t rc; - - if (!file) { - gnutls_assert(); - return CDK_Inv_Value; - } - - rc = cdk_stream_open(file, &inp); - if (rc) { - gnutls_assert(); - return rc; - } - - idx_name = keydb_idx_mkname(file); - if (!idx_name) { - cdk_stream_close(inp); - gnutls_assert(); - return CDK_Out_Of_Core; - } - rc = cdk_stream_create(idx_name, &out); - cdk_free(idx_name); - if (rc) { - cdk_stream_close(inp); - gnutls_assert(); - return rc; - } - - cdk_pkt_new(&pkt); - while (!cdk_stream_eof(inp)) { - off_t pos = cdk_stream_tell(inp); - - rc = cdk_pkt_read(inp, pkt, 1); - if (rc) { - _cdk_log_debug - ("index build failed packet off=%lu\n", - (unsigned long) pos); - /* FIXME: The index is incomplete */ - break; - } - if (pkt->pkttype == CDK_PKT_PUBLIC_KEY || - pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY) { - _cdk_u32tobuf(pos, buf); - cdk_pk_get_keyid(pkt->pkt.public_key, keyid); - _cdk_u32tobuf(keyid[0], buf + 4); - _cdk_u32tobuf(keyid[1], buf + 8); - cdk_pk_get_fingerprint(pkt->pkt.public_key, - buf + 12); - cdk_stream_write(out, buf, 4 + 8 + KEY_FPR_LEN); - } - cdk_pkt_free(pkt); - } - - cdk_pkt_release(pkt); - - cdk_stream_close(out); - cdk_stream_close(inp); - gnutls_assert(); - return rc; -} - - -/** - * cdk_keydb_idx_rebuild: - * @hd: key database handle - * - * Rebuild the key index files for the given key database. - **/ -cdk_error_t -cdk_keydb_idx_rebuild(cdk_keydb_hd_t db, cdk_keydb_search_t dbs) -{ - struct stat stbuf; - char *tmp_idx_name; - cdk_error_t rc; - int err; - - if (!db || !db->name || !dbs) { - gnutls_assert(); - return CDK_Inv_Value; - } - if (db->secret) - return 0; - - tmp_idx_name = keydb_idx_mkname(db->name); - if (!tmp_idx_name) { - gnutls_assert(); - return CDK_Out_Of_Core; - } - err = stat(tmp_idx_name, &stbuf); - cdk_free(tmp_idx_name); - /* This function expects an existing index which can be rebuild, - if no index exists we do not build one and just return. */ - if (err) - return 0; - - cdk_stream_close(dbs->idx); - dbs->idx = NULL; - if (!dbs->idx_name) { - dbs->idx_name = keydb_idx_mkname(db->name); - if (!dbs->idx_name) { - gnutls_assert(); - return CDK_Out_Of_Core; - } - } - rc = keydb_idx_build(db->name); - if (!rc) - rc = cdk_stream_open(dbs->idx_name, &dbs->idx); - else - gnutls_assert(); - return rc; -} - - -/** - * cdk_keydb_new_from_mem: - * @r_hd: The keydb output handle. - * @secret: does the stream contain secret key data - * @armor: the stream is base64 - * @data: The raw key data. - * @datlen: The length of the raw data. - * - * Create a new keyring db handle from the contents of a buffer. - */ -cdk_error_t -cdk_keydb_new_from_mem(cdk_keydb_hd_t * r_db, int secret, int armor, - const void *data, size_t datlen) -{ - cdk_keydb_hd_t db; - cdk_error_t rc; - - if (!r_db) { - gnutls_assert(); - return CDK_Inv_Value; - } - *r_db = NULL; - db = calloc(1, sizeof *db); - rc = cdk_stream_tmp_from_mem(data, datlen, &db->fp); - if (!db->fp) { - cdk_free(db); - gnutls_assert(); - return rc; - } - - if (armor) - cdk_stream_set_armor_flag(db->fp, 0); - db->type = CDK_DBTYPE_DATA; - db->secret = secret; - *r_db = db; - return 0; -} - -/** - * cdk_keydb_free: - * @hd: the keydb object - * - * Free the keydb object. - **/ -void cdk_keydb_free(cdk_keydb_hd_t hd) -{ - if (!hd) - return; - - if (hd->name) { - cdk_free(hd->name); - hd->name = NULL; - } - - if (hd->fp && !hd->fp_ref) { - cdk_stream_close(hd->fp); - hd->fp = NULL; - } - - - hd->isopen = 0; - hd->secret = 0; - cdk_free(hd); -} - - -static cdk_error_t -_cdk_keydb_open(cdk_keydb_hd_t hd, cdk_stream_t * ret_kr) -{ - cdk_error_t rc; - cdk_stream_t kr; - - if (!hd || !ret_kr) { - gnutls_assert(); - return CDK_Inv_Value; - } - - rc = 0; - if ((hd->type == CDK_DBTYPE_DATA) - && hd->fp) { - kr = hd->fp; - cdk_stream_seek(kr, 0); - } else if (hd->type == CDK_DBTYPE_PK_KEYRING || - hd->type == CDK_DBTYPE_SK_KEYRING) { - rc = cdk_stream_open(hd->name, &kr); - - if (rc) - goto leave; - } else { - gnutls_assert(); - return CDK_Inv_Mode; - } - - leave: - - *ret_kr = kr; - return rc; -} - - -static int find_by_keyid(cdk_kbnode_t knode, cdk_keydb_search_t ks) -{ - cdk_kbnode_t node; - u32 keyid[2]; - - for (node = knode; node; node = node->next) { - if (node->pkt->pkttype == CDK_PKT_PUBLIC_KEY || - node->pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY || - node->pkt->pkttype == CDK_PKT_SECRET_KEY || - node->pkt->pkttype == CDK_PKT_SECRET_SUBKEY) { - _cdk_pkt_get_keyid(node->pkt, keyid); - switch (ks->type) { - case CDK_DBSEARCH_SHORT_KEYID: - if (keyid[1] == ks->u.keyid[1]) - return 1; - break; - - case CDK_DBSEARCH_KEYID: - if (KEYID_CMP(keyid, ks->u.keyid)) - return 1; - break; - - default: - _cdk_log_debug - ("find_by_keyid: invalid mode = %d\n", - ks->type); - return 0; - } - } - } - return 0; -} - - -static int find_by_fpr(cdk_kbnode_t knode, cdk_keydb_search_t ks) -{ - cdk_kbnode_t node; - byte fpr[KEY_FPR_LEN]; - - if (ks->type != CDK_DBSEARCH_FPR) - return 0; - - for (node = knode; node; node = node->next) { - if (node->pkt->pkttype == CDK_PKT_PUBLIC_KEY || - node->pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY || - node->pkt->pkttype == CDK_PKT_SECRET_KEY || - node->pkt->pkttype == CDK_PKT_SECRET_SUBKEY) { - _cdk_pkt_get_fingerprint(node->pkt, fpr); - if (!memcmp(ks->u.fpr, fpr, KEY_FPR_LEN)) - return 1; - break; - } - } - - return 0; -} - - -static int find_by_pattern(cdk_kbnode_t knode, cdk_keydb_search_t ks) -{ - cdk_kbnode_t node; - size_t uidlen; - char *name; - - for (node = knode; node; node = node->next) { - if (node->pkt->pkttype != CDK_PKT_USER_ID) - continue; - if (node->pkt->pkt.user_id->attrib_img != NULL) - continue; /* Skip attribute packets. */ - uidlen = node->pkt->pkt.user_id->len; - name = node->pkt->pkt.user_id->name; - switch (ks->type) { - case CDK_DBSEARCH_EXACT: - if (name && - (strlen(ks->u.pattern) == uidlen && - !strncmp(ks->u.pattern, name, uidlen))) - return 1; - break; - - case CDK_DBSEARCH_SUBSTR: - if (uidlen > 65536) - break; - if (name && strlen(ks->u.pattern) > uidlen) - break; - if (name - && _cdk_memistr(name, uidlen, ks->u.pattern)) - return 1; - break; - - default: /* Invalid mode */ - return 0; - } - } - return 0; -} - -static cdk_error_t idx_init(cdk_keydb_hd_t db, cdk_keydb_search_t dbs) -{ - cdk_error_t ec, rc = 0; - - if (cdk_stream_get_length(db->fp) < 524288) { - dbs->no_cache = 1; - goto leave; - } - - dbs->idx_name = keydb_idx_mkname(db->name); - if (!dbs->idx_name) { - rc = CDK_Out_Of_Core; - goto leave; - } - ec = cdk_stream_open(dbs->idx_name, &dbs->idx); - - if (ec && !db->secret) { - rc = keydb_idx_build(db->name); - if (!rc) - rc = cdk_stream_open(dbs->idx_name, &dbs->idx); - if (!rc) { - _cdk_log_debug("create key index table\n"); - } else { - /* This is no real error, it just means we can't create - the index at the given directory. maybe we've no write - access. in this case, we simply disable the index. */ - _cdk_log_debug("disable key index table err=%d\n", - rc); - rc = 0; - dbs->no_cache = 1; - } - } - - leave: - - return rc; -} - -/** - * cdk_keydb_search_start: - * @st: search handle - * @db: key database handle - * @type: specifies the search type - * @desc: description which depends on the type - * - * Create a new keydb search object. - **/ -cdk_error_t -cdk_keydb_search_start(cdk_keydb_search_t * st, cdk_keydb_hd_t db, - int type, void *desc) -{ - u32 *keyid; - char *p, tmp[3]; - int i; - cdk_error_t rc; - - if (!db) { - gnutls_assert(); - return CDK_Inv_Value; - } - if (type != CDK_DBSEARCH_NEXT && !desc) { - gnutls_assert(); - return CDK_Inv_Mode; - } - - *st = cdk_calloc(1, sizeof(cdk_keydb_search_s)); - if (!(*st)) { - gnutls_assert(); - return CDK_Out_Of_Core; - } - - rc = idx_init(db, *st); - if (rc != CDK_Success) { - free(*st); - gnutls_assert(); - return rc; - } - - (*st)->type = type; - switch (type) { - case CDK_DBSEARCH_EXACT: - case CDK_DBSEARCH_SUBSTR: - cdk_free((*st)->u.pattern); - (*st)->u.pattern = cdk_strdup(desc); - if (!(*st)->u.pattern) { - cdk_free(*st); - gnutls_assert(); - return CDK_Out_Of_Core; - } - break; - - case CDK_DBSEARCH_SHORT_KEYID: - keyid = desc; - (*st)->u.keyid[1] = keyid[0]; - break; - - case CDK_DBSEARCH_KEYID: - keyid = desc; - (*st)->u.keyid[0] = keyid[0]; - (*st)->u.keyid[1] = keyid[1]; - break; - - case CDK_DBSEARCH_FPR: - memcpy((*st)->u.fpr, desc, KEY_FPR_LEN); - break; - - case CDK_DBSEARCH_NEXT: - break; - - case CDK_DBSEARCH_AUTO: - /* Override the type with the actual db search type. */ - (*st)->type = classify_data(desc, strlen(desc)); - switch ((*st)->type) { - case CDK_DBSEARCH_SUBSTR: - case CDK_DBSEARCH_EXACT: - cdk_free((*st)->u.pattern); - p = (*st)->u.pattern = cdk_strdup(desc); - if (!p) { - cdk_free(*st); - gnutls_assert(); - return CDK_Out_Of_Core; - } - break; - - case CDK_DBSEARCH_SHORT_KEYID: - case CDK_DBSEARCH_KEYID: - p = desc; - if (!strncmp(p, "0x", 2)) - p += 2; - if (strlen(p) == 8) { - (*st)->u.keyid[0] = 0; - (*st)->u.keyid[1] = strtoul(p, NULL, 16); - } else if (strlen(p) == 16) { - (*st)->u.keyid[0] = strtoul(p, NULL, 16); - (*st)->u.keyid[1] = - strtoul(p + 8, NULL, 16); - } else { /* Invalid key ID object. */ - cdk_free(*st); - gnutls_assert(); - return CDK_Inv_Mode; - } - break; - - case CDK_DBSEARCH_FPR: - p = desc; - if (strlen(p) != 2 * KEY_FPR_LEN) { - cdk_free(*st); - gnutls_assert(); - return CDK_Inv_Mode; - } - for (i = 0; i < KEY_FPR_LEN; i++) { - tmp[0] = p[2 * i]; - tmp[1] = p[2 * i + 1]; - tmp[2] = 0x00; - (*st)->u.fpr[i] = strtoul(tmp, NULL, 16); - } - break; - } - break; - - default: - cdk_free(*st); - _cdk_log_debug - ("cdk_keydb_search_start: invalid mode = %d\n", type); - gnutls_assert(); - return CDK_Inv_Mode; - } - - return 0; -} - -void cdk_keydb_search_release(cdk_keydb_search_t st) -{ - if (st == NULL) - return; - - if (st->idx) - cdk_stream_close(st->idx); - - if (st->type == CDK_DBSEARCH_EXACT - || st->type == CDK_DBSEARCH_SUBSTR) - cdk_free(st->u.pattern); - - cdk_free(st); -} - -/** - * cdk_keydb_search: - * @st: the search handle - * @hd: the keydb object - * @ret_key: kbnode object to store the key - * - * Search for a key in the given keyring. The search mode is handled - * via @ks. If the key was found, @ret_key contains the key data. - **/ -cdk_error_t -cdk_keydb_search(cdk_keydb_search_t st, cdk_keydb_hd_t hd, - cdk_kbnode_t * ret_key) -{ - cdk_stream_t kr; - cdk_kbnode_t knode; - cdk_error_t rc = 0; - int key_found = 0; - - if (!hd || !ret_key || !st) { - gnutls_assert(); - return CDK_Inv_Value; - } - - *ret_key = NULL; - kr = NULL; - - rc = _cdk_keydb_open(hd, &kr); - if (rc) { - gnutls_assert(); - return rc; - } - - knode = NULL; - - while (!key_found && !rc) { - if (st->type == CDK_DBSEARCH_NEXT) - cdk_stream_seek(kr, st->off); - - rc = cdk_keydb_get_keyblock(kr, &knode, 1); - - if (rc) { - if (rc == CDK_EOF) - break; - else { - gnutls_assert(); - return rc; - } - } - - switch (st->type) { - case CDK_DBSEARCH_SHORT_KEYID: - case CDK_DBSEARCH_KEYID: - key_found = find_by_keyid(knode, st); - break; - - case CDK_DBSEARCH_FPR: - key_found = find_by_fpr(knode, st); - break; - - case CDK_DBSEARCH_EXACT: - case CDK_DBSEARCH_SUBSTR: - key_found = find_by_pattern(knode, st); - break; - - case CDK_DBSEARCH_NEXT: - st->off = cdk_stream_tell(kr); - key_found = knode ? 1 : 0; - break; - } - - if (key_found) { - break; - } - - cdk_kbnode_release(knode); - knode = NULL; - } - - if (key_found && rc == CDK_EOF) - rc = 0; - else if (rc == CDK_EOF && !key_found) { - gnutls_assert(); - rc = CDK_Error_No_Key; - } - *ret_key = key_found ? knode : NULL; - return rc; -} - -cdk_error_t -cdk_keydb_get_bykeyid(cdk_keydb_hd_t hd, u32 * keyid, - cdk_kbnode_t * ret_key) -{ - cdk_error_t rc; - cdk_keydb_search_t st; - - if (!hd || !keyid || !ret_key) { - gnutls_assert(); - return CDK_Inv_Value; - } - - rc = cdk_keydb_search_start(&st, hd, CDK_DBSEARCH_KEYID, keyid); - if (!rc) - rc = cdk_keydb_search(st, hd, ret_key); - - cdk_keydb_search_release(st); - return rc; -} - - -cdk_error_t -cdk_keydb_get_byfpr(cdk_keydb_hd_t hd, const byte * fpr, - cdk_kbnode_t * r_key) -{ - cdk_error_t rc; - cdk_keydb_search_t st; - - if (!hd || !fpr || !r_key) { - gnutls_assert(); - return CDK_Inv_Value; - } - - rc = cdk_keydb_search_start(&st, hd, CDK_DBSEARCH_FPR, - (byte *) fpr); - if (!rc) - rc = cdk_keydb_search(st, hd, r_key); - - cdk_keydb_search_release(st); - return rc; -} - - -cdk_error_t -cdk_keydb_get_bypattern(cdk_keydb_hd_t hd, const char *patt, - cdk_kbnode_t * ret_key) -{ - cdk_error_t rc; - cdk_keydb_search_t st; - - if (!hd || !patt || !ret_key) { - gnutls_assert(); - return CDK_Inv_Value; - } - - rc = cdk_keydb_search_start(&st, hd, CDK_DBSEARCH_SUBSTR, - (char *) patt); - if (!rc) - rc = cdk_keydb_search(st, hd, ret_key); - - if (rc) - gnutls_assert(); - - cdk_keydb_search_release(st); - return rc; -} - - -static int keydb_check_key(cdk_packet_t pkt) -{ - cdk_pkt_pubkey_t pk; - int is_sk, valid; - - if (pkt->pkttype == CDK_PKT_PUBLIC_KEY || - pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY) { - pk = pkt->pkt.public_key; - is_sk = 0; - } else if (pkt->pkttype == CDK_PKT_SECRET_KEY || - pkt->pkttype == CDK_PKT_SECRET_SUBKEY) { - pk = pkt->pkt.secret_key->pk; - is_sk = 1; - } else /* No key object. */ - return 0; - valid = !pk->is_revoked && !pk->has_expired; - if (is_sk) - return valid; - return valid && !pk->is_invalid; -} - - -/* Find the first kbnode with the requested packet type - that represents a valid key. */ -static cdk_kbnode_t -kbnode_find_valid(cdk_kbnode_t root, cdk_packet_type_t pkttype) -{ - cdk_kbnode_t n; - - for (n = root; n; n = n->next) { - if (n->pkt->pkttype != pkttype) - continue; - if (keydb_check_key(n->pkt)) - return n; - } - - return NULL; -} - - -static cdk_kbnode_t -keydb_find_byusage(cdk_kbnode_t root, int req_usage, int is_pk) -{ - cdk_kbnode_t node, key; - int req_type; - long timestamp; - - req_type = is_pk ? CDK_PKT_PUBLIC_KEY : CDK_PKT_SECRET_KEY; - if (!req_usage) - return kbnode_find_valid(root, req_type); - - node = cdk_kbnode_find(root, req_type); - if (node && !keydb_check_key(node->pkt)) - return NULL; - - key = NULL; - timestamp = 0; - /* We iteratre over the all nodes and search for keys or - subkeys which match the usage and which are not invalid. - A timestamp is used to figure out the newest valid key. */ - for (node = root; node; node = node->next) { - if (is_pk && (node->pkt->pkttype == CDK_PKT_PUBLIC_KEY || - node->pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY) - && keydb_check_key(node->pkt) - && (node->pkt->pkt.public_key-> - pubkey_usage & req_usage)) { - if (node->pkt->pkt.public_key->timestamp > - timestamp) - key = node; - } - if (!is_pk && (node->pkt->pkttype == CDK_PKT_SECRET_KEY || - node->pkt->pkttype == CDK_PKT_SECRET_SUBKEY) - && keydb_check_key(node->pkt) - && (node->pkt->pkt.secret_key->pk-> - pubkey_usage & req_usage)) { - if (node->pkt->pkt.secret_key->pk->timestamp > - timestamp) - key = node; - } - - } - return key; -} - - -static cdk_kbnode_t -keydb_find_bykeyid(cdk_kbnode_t root, const u32 * keyid, int search_mode) -{ - cdk_kbnode_t node; - u32 kid[2]; - - for (node = root; node; node = node->next) { - if (!_cdk_pkt_get_keyid(node->pkt, kid)) - continue; - if (search_mode == CDK_DBSEARCH_SHORT_KEYID - && kid[1] == keyid[1]) - return node; - else if (kid[0] == keyid[0] && kid[1] == keyid[1]) - return node; - } - return NULL; -} - - -cdk_error_t -_cdk_keydb_get_sk_byusage(cdk_keydb_hd_t hd, const char *name, - cdk_seckey_t * ret_sk, int usage) -{ - cdk_kbnode_t knode = NULL; - cdk_kbnode_t node, sk_node, pk_node; - cdk_pkt_seckey_t sk; - cdk_error_t rc; - const char *s; - int pkttype; - cdk_keydb_search_t st; - - if (!ret_sk || !usage) { - gnutls_assert(); - return CDK_Inv_Value; - } - - if (!hd) { - gnutls_assert(); - return CDK_Error_No_Keyring; - } - - *ret_sk = NULL; - rc = cdk_keydb_search_start(&st, hd, CDK_DBSEARCH_AUTO, - (char *) name); - if (rc) { - gnutls_assert(); - return rc; - } - - rc = cdk_keydb_search(st, hd, &knode); - if (rc) { - gnutls_assert(); - return rc; - } - - cdk_keydb_search_release(st); - - sk_node = keydb_find_byusage(knode, usage, 0); - if (!sk_node) { - cdk_kbnode_release(knode); - gnutls_assert(); - return CDK_Unusable_Key; - } - - /* We clone the node with the secret key to avoid that the - packet will be released. */ - _cdk_kbnode_clone(sk_node); - sk = sk_node->pkt->pkt.secret_key; - - for (node = knode; node; node = node->next) { - if (node->pkt->pkttype == CDK_PKT_USER_ID) { - s = node->pkt->pkt.user_id->name; - if (sk && !sk->pk->uid - && _cdk_memistr(s, strlen(s), name)) { - _cdk_copy_userid(&sk->pk->uid, - node->pkt->pkt.user_id); - break; - } - } - } - - /* To find the self signature, we need the primary public key because - the selected secret key might be different from the primary key. */ - pk_node = cdk_kbnode_find(knode, CDK_PKT_SECRET_KEY); - if (!pk_node) { - cdk_kbnode_release(knode); - gnutls_assert(); - return CDK_Unusable_Key; - } - node = find_selfsig_node(knode, pk_node->pkt->pkt.secret_key->pk); - if (sk && sk->pk && sk->pk->uid && node) - _cdk_copy_signature(&sk->pk->uid->selfsig, - node->pkt->pkt.signature); - - /* We only release the outer packet. */ - _cdk_pkt_detach_free(sk_node->pkt, &pkttype, (void *) &sk); - cdk_kbnode_release(knode); - *ret_sk = sk; - return rc; -} - - -cdk_error_t -_cdk_keydb_get_pk_byusage(cdk_keydb_hd_t hd, const char *name, - cdk_pubkey_t * ret_pk, int usage) -{ - cdk_kbnode_t knode, node, pk_node; - cdk_pkt_pubkey_t pk; - const char *s; - cdk_error_t rc; - cdk_keydb_search_t st; - - if (!ret_pk || !usage) { - gnutls_assert(); - return CDK_Inv_Value; - } - if (!hd) { - gnutls_assert(); - return CDK_Error_No_Keyring; - } - - *ret_pk = NULL; - rc = cdk_keydb_search_start(&st, hd, CDK_DBSEARCH_AUTO, - (char *) name); - if (!rc) - rc = cdk_keydb_search(st, hd, &knode); - if (rc) { - gnutls_assert(); - return rc; - } - - cdk_keydb_search_release(st); - - node = keydb_find_byusage(knode, usage, 1); - if (!node) { - cdk_kbnode_release(knode); - gnutls_assert(); - return CDK_Unusable_Key; - } - - pk = NULL; - _cdk_copy_pubkey(&pk, node->pkt->pkt.public_key); - for (node = knode; node; node = node->next) { - if (node->pkt->pkttype == CDK_PKT_USER_ID) { - s = node->pkt->pkt.user_id->name; - if (pk && !pk->uid - && _cdk_memistr(s, strlen(s), name)) { - _cdk_copy_userid(&pk->uid, - node->pkt->pkt.user_id); - break; - } - } - } - - /* Same as in the sk code, the selected key can be a sub key - and thus we need the primary key to find the self sig. */ - pk_node = cdk_kbnode_find(knode, CDK_PKT_PUBLIC_KEY); - if (!pk_node) { - cdk_kbnode_release(knode); - gnutls_assert(); - return CDK_Unusable_Key; - } - node = find_selfsig_node(knode, pk_node->pkt->pkt.public_key); - if (pk && pk->uid && node) - _cdk_copy_signature(&pk->uid->selfsig, - node->pkt->pkt.signature); - cdk_kbnode_release(knode); - - *ret_pk = pk; - return rc; -} - - -/** - * cdk_keydb_get_pk: - * @hd: key db handle - * @keyid: keyid of the key - * @r_pk: the allocated public key - * - * Perform a key database search by keyid and return the raw public - * key without any signatures or user id's. - **/ -cdk_error_t -cdk_keydb_get_pk(cdk_keydb_hd_t hd, u32 * keyid, cdk_pubkey_t * r_pk) -{ - cdk_kbnode_t knode = NULL, node; - cdk_pubkey_t pk; - cdk_error_t rc; - size_t s_type; - int pkttype; - cdk_keydb_search_t st; - - if (!keyid || !r_pk) { - gnutls_assert(); - return CDK_Inv_Value; - } - if (!hd) { - gnutls_assert(); - return CDK_Error_No_Keyring; - } - - *r_pk = NULL; - s_type = !keyid[0] ? CDK_DBSEARCH_SHORT_KEYID : CDK_DBSEARCH_KEYID; - rc = cdk_keydb_search_start(&st, hd, s_type, keyid); - if (rc) { - gnutls_assert(); - return rc; - } - rc = cdk_keydb_search(st, hd, &knode); - cdk_keydb_search_release(st); - if (rc) { - gnutls_assert(); - return rc; - } - - node = keydb_find_bykeyid(knode, keyid, s_type); - if (!node) { - cdk_kbnode_release(knode); - gnutls_assert(); - return CDK_Error_No_Key; - } - - /* See comment in cdk_keydb_get_sk() */ - _cdk_pkt_detach_free(node->pkt, &pkttype, (void *) &pk); - *r_pk = pk; - _cdk_kbnode_clone(node); - cdk_kbnode_release(knode); - - return rc; -} - - -/** - * cdk_keydb_get_sk: - * @hd: key db handle - * @keyid: the keyid of the key - * @ret_sk: the allocated secret key - * - * Perform a key database search by keyid and return - * only the raw secret key without the additional nodes, - * like the user id or the signatures. - **/ -cdk_error_t -cdk_keydb_get_sk(cdk_keydb_hd_t hd, u32 * keyid, cdk_seckey_t * ret_sk) -{ - cdk_kbnode_t snode, node; - cdk_seckey_t sk; - cdk_error_t rc; - int pkttype; - - if (!keyid || !ret_sk) { - gnutls_assert(); - return CDK_Inv_Value; - } - if (!hd) { - gnutls_assert(); - return CDK_Error_No_Keyring; - } - - *ret_sk = NULL; - rc = cdk_keydb_get_bykeyid(hd, keyid, &snode); - if (rc) { - gnutls_assert(); - return rc; - } - - node = keydb_find_bykeyid(snode, keyid, CDK_DBSEARCH_KEYID); - if (!node) { - cdk_kbnode_release(snode); - gnutls_assert(); - return CDK_Error_No_Key; - } - - /* We need to release the packet itself but not its contents - and thus we detach the openpgp packet and release the structure. */ - _cdk_pkt_detach_free(node->pkt, &pkttype, (void *) &sk); - _cdk_kbnode_clone(node); - cdk_kbnode_release(snode); - - *ret_sk = sk; - return 0; -} - - -static int is_selfsig(cdk_kbnode_t node, const u32 * keyid) -{ - cdk_pkt_signature_t sig; - - if (node->pkt->pkttype != CDK_PKT_SIGNATURE) - return 0; - sig = node->pkt->pkt.signature; - if ((sig->sig_class >= 0x10 && sig->sig_class <= 0x13) && - sig->keyid[0] == keyid[0] && sig->keyid[1] == keyid[1]) - return 1; - - return 0; -} - - -/* Find the newest self signature for the public key @pk - and return the signature node. */ -static cdk_kbnode_t -find_selfsig_node(cdk_kbnode_t key, cdk_pkt_pubkey_t pk) -{ - cdk_kbnode_t n, sig; - unsigned int ts; - u32 keyid[2]; - - cdk_pk_get_keyid(pk, keyid); - sig = NULL; - ts = 0; - for (n = key; n; n = n->next) { - if (is_selfsig(n, keyid) - && n->pkt->pkt.signature->timestamp > ts) { - ts = n->pkt->pkt.signature->timestamp; - sig = n; - } - } - - return sig; -} - -static unsigned int key_usage_to_cdk_usage(unsigned int usage) -{ - unsigned key_usage = 0; - - if (usage & 0x01) /* cert + sign data */ - key_usage |= CDK_KEY_USG_CERT_SIGN; - if (usage & 0x02) /* cert + sign data */ - key_usage |= CDK_KEY_USG_DATA_SIGN; - if (usage & 0x04) /* encrypt comm. + storage */ - key_usage |= CDK_KEY_USG_COMM_ENCR; - if (usage & 0x08) /* encrypt comm. + storage */ - key_usage |= CDK_KEY_USG_STORAGE_ENCR; - if (usage & 0x10) /* encrypt comm. + storage */ - key_usage |= CDK_KEY_USG_SPLIT_KEY; - if (usage & 0x20) - key_usage |= CDK_KEY_USG_AUTH; - if (usage & 0x80) /* encrypt comm. + storage */ - key_usage |= CDK_KEY_USG_SHARED_KEY; - - return key_usage; -} - -static cdk_error_t keydb_merge_selfsig(cdk_kbnode_t key, u32 * keyid) -{ - cdk_kbnode_t node, kbnode, unode; - cdk_subpkt_t s = NULL; - cdk_pkt_signature_t sig = NULL; - cdk_pkt_userid_t uid = NULL; - const byte *symalg = NULL, *hashalg = NULL, *compalg = NULL; - size_t nsymalg = 0, nhashalg = 0, ncompalg = 0, n = 0; - size_t key_expire = 0; - - if (!key) { - gnutls_assert(); - return CDK_Inv_Value; - } - - for (node = key; node; node = node->next) { - if (!is_selfsig(node, keyid)) - continue; - unode = cdk_kbnode_find_prev(key, node, CDK_PKT_USER_ID); - if (!unode) { - gnutls_assert(); - return CDK_Error_No_Key; - } - uid = unode->pkt->pkt.user_id; - sig = node->pkt->pkt.signature; - s = cdk_subpkt_find(sig->hashed, - CDK_SIGSUBPKT_PRIMARY_UID); - if (s) - uid->is_primary = 1; - s = cdk_subpkt_find(sig->hashed, CDK_SIGSUBPKT_FEATURES); - if (s && s->size == 1 && s->d[0] & 0x01) - uid->mdc_feature = 1; - s = cdk_subpkt_find(sig->hashed, CDK_SIGSUBPKT_KEY_EXPIRE); - if (s && s->size == 4) - key_expire = _cdk_buftou32(s->d); - s = cdk_subpkt_find(sig->hashed, CDK_SIGSUBPKT_PREFS_SYM); - if (s) { - symalg = s->d; - nsymalg = s->size; - n += s->size + 1; - } - s = cdk_subpkt_find(sig->hashed, CDK_SIGSUBPKT_PREFS_HASH); - if (s) { - hashalg = s->d; - nhashalg = s->size; - n += s->size + 1; - } - s = cdk_subpkt_find(sig->hashed, CDK_SIGSUBPKT_PREFS_ZIP); - if (s) { - compalg = s->d; - ncompalg = s->size; - n += s->size + 1; - } - if (uid->prefs != NULL) - cdk_free(uid->prefs); - if (!n || !hashalg || !compalg || !symalg) - uid->prefs = NULL; - else { - uid->prefs = - cdk_calloc(1, sizeof(*uid->prefs) * (n + 1)); - if (!uid->prefs) { - gnutls_assert(); - return CDK_Out_Of_Core; - } - n = 0; - for (; nsymalg; nsymalg--, n++) { - uid->prefs[n].type = CDK_PREFTYPE_SYM; - uid->prefs[n].value = *symalg++; - } - for (; nhashalg; nhashalg--, n++) { - uid->prefs[n].type = CDK_PREFTYPE_HASH; - uid->prefs[n].value = *hashalg++; - } - for (; ncompalg; ncompalg--, n++) { - uid->prefs[n].type = CDK_PREFTYPE_ZIP; - uid->prefs[n].value = *compalg++; - } - - uid->prefs[n].type = CDK_PREFTYPE_NONE; /* end of list marker */ - uid->prefs[n].value = 0; - uid->prefs_size = n; - } - } - - /* Now we add the extracted information to the primary key. */ - kbnode = cdk_kbnode_find(key, CDK_PKT_PUBLIC_KEY); - if (kbnode) { - cdk_pkt_pubkey_t pk = kbnode->pkt->pkt.public_key; - if (uid && uid->prefs && n) { - if (pk->prefs != NULL) - cdk_free(pk->prefs); - pk->prefs = _cdk_copy_prefs(uid->prefs); - pk->prefs_size = n; - } - if (key_expire) { - pk->expiredate = pk->timestamp + key_expire; - pk->has_expired = - pk->expiredate > - (u32) gnutls_time(NULL) ? 0 : 1; - } - - pk->is_invalid = 0; - } - - return 0; -} - - -static cdk_error_t -keydb_parse_allsigs(cdk_kbnode_t knode, cdk_keydb_hd_t hd, int check) -{ - cdk_kbnode_t node, kb; - cdk_pkt_signature_t sig; - cdk_pkt_pubkey_t pk; - cdk_subpkt_t s = NULL; - u32 expiredate = 0, curtime = (u32) gnutls_time(NULL); - u32 keyid[2]; - - if (!knode) { - gnutls_assert(); - return CDK_Inv_Value; - } - if (check && !hd) { - gnutls_assert(); - return CDK_Inv_Mode; - } - - kb = cdk_kbnode_find(knode, CDK_PKT_SECRET_KEY); - if (kb) - return 0; - - /* Reset */ - for (node = knode; node; node = node->next) { - if (node->pkt->pkttype == CDK_PKT_USER_ID) - node->pkt->pkt.user_id->is_revoked = 0; - else if (node->pkt->pkttype == CDK_PKT_PUBLIC_KEY || - node->pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY) - node->pkt->pkt.public_key->is_revoked = 0; - } - - kb = cdk_kbnode_find(knode, CDK_PKT_PUBLIC_KEY); - if (!kb) { - gnutls_assert(); - return CDK_Wrong_Format; - } - cdk_pk_get_keyid(kb->pkt->pkt.public_key, keyid); - - for (node = knode; node; node = node->next) { - if (node->pkt->pkttype == CDK_PKT_SIGNATURE) { - sig = node->pkt->pkt.signature; - /* Revocation certificates for primary keys */ - if (sig->sig_class == 0x20) { - kb = cdk_kbnode_find_prev(knode, node, - CDK_PKT_PUBLIC_KEY); - if (kb) { - kb->pkt->pkt.public_key-> - is_revoked = 1; - if (check) - _cdk_pk_check_sig(hd, kb, - node, - NULL, - NULL); - } else { - gnutls_assert(); - return CDK_Error_No_Key; - } - } - /* Revocation certificates for subkeys */ - else if (sig->sig_class == 0x28) { - kb = cdk_kbnode_find_prev(knode, node, - CDK_PKT_PUBLIC_SUBKEY); - if (kb) { - kb->pkt->pkt.public_key-> - is_revoked = 1; - if (check) - _cdk_pk_check_sig(hd, kb, - node, - NULL, - NULL); - } else { - gnutls_assert(); - return CDK_Error_No_Key; - } - } - /* Revocation certificates for user ID's */ - else if (sig->sig_class == 0x30) { - if (sig->keyid[0] != keyid[0] - || sig->keyid[1] != keyid[1]) - continue; /* revokes an earlier signature, no userID. */ - kb = cdk_kbnode_find_prev(knode, node, - CDK_PKT_USER_ID); - if (kb) { - kb->pkt->pkt.user_id->is_revoked = - 1; - if (check) - _cdk_pk_check_sig(hd, kb, - node, - NULL, - NULL); - } else { - gnutls_assert(); - return CDK_Error_No_Key; - } - } - /* Direct certificates for primary keys */ - else if (sig->sig_class == 0x1F) { - kb = cdk_kbnode_find_prev(knode, node, - CDK_PKT_PUBLIC_KEY); - if (kb) { - pk = kb->pkt->pkt.public_key; - pk->is_invalid = 0; - s = cdk_subpkt_find(node->pkt->pkt. - signature-> - hashed, - CDK_SIGSUBPKT_KEY_EXPIRE); - if (s && s->size == 4) { - expiredate = - _cdk_buftou32(s->d); - pk->expiredate = - pk->timestamp + - expiredate; - pk->has_expired = - pk->expiredate > - curtime ? 0 : 1; - } - if (check) - _cdk_pk_check_sig(hd, kb, - node, - NULL, - NULL); - } else { - gnutls_assert(); - return CDK_Error_No_Key; - } - } - /* Direct certificates for subkeys */ - else if (sig->sig_class == 0x18) { - kb = cdk_kbnode_find_prev(knode, node, - CDK_PKT_PUBLIC_SUBKEY); - if (kb) { - pk = kb->pkt->pkt.public_key; - pk->is_invalid = 0; - s = cdk_subpkt_find(node->pkt->pkt. - signature-> - hashed, - CDK_SIGSUBPKT_KEY_EXPIRE); - if (s && s->size == 4) { - expiredate = - _cdk_buftou32(s->d); - pk->expiredate = - pk->timestamp + - expiredate; - pk->has_expired = - pk->expiredate > - curtime ? 0 : 1; - } - if (check) - _cdk_pk_check_sig(hd, kb, - node, - NULL, - NULL); - } else { - gnutls_assert(); - return CDK_Error_No_Key; - } - } - } - } - node = cdk_kbnode_find(knode, CDK_PKT_PUBLIC_KEY); - if (node && node->pkt->pkt.public_key->version == 3) { - /* v3 public keys have no additonal signatures for the key directly. - we say the key is valid when we have at least a self signature. */ - pk = node->pkt->pkt.public_key; - for (node = knode; node; node = node->next) { - if (is_selfsig(node, keyid)) { - pk->is_invalid = 0; - break; - } - } - } - if (node && (node->pkt->pkt.public_key->is_revoked || - node->pkt->pkt.public_key->has_expired)) { - /* If the primary key has been revoked, mark all subkeys as invalid - because without a primary key they are not useable */ - for (node = knode; node; node = node->next) { - if (node->pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY) - node->pkt->pkt.public_key->is_invalid = 1; - } - } - - return 0; -} - -static void -add_key_usage(cdk_kbnode_t knode, u32 keyid[2], unsigned int usage) -{ - cdk_kbnode_t p, ctx; - cdk_packet_t pkt; - - ctx = NULL; - while ((p = cdk_kbnode_walk(knode, &ctx, 0))) { - pkt = cdk_kbnode_get_packet(p); - if ((pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY - || pkt->pkttype == CDK_PKT_PUBLIC_KEY) - && pkt->pkt.public_key->keyid[0] == keyid[0] - && pkt->pkt.public_key->keyid[1] == keyid[1]) { - pkt->pkt.public_key->pubkey_usage = usage; - return; - } - } - return; -} - -cdk_error_t -cdk_keydb_get_keyblock(cdk_stream_t inp, cdk_kbnode_t * r_knode, unsigned public) -{ - cdk_packet_t pkt; - cdk_kbnode_t knode, node; - cdk_desig_revoker_t revkeys; - cdk_error_t rc; - u32 keyid[2], main_keyid[2]; - off_t old_off; - int key_seen, got_key; - - if (!inp || !r_knode) { - gnutls_assert(); - return CDK_Inv_Value; - } - - /* Reset all values. */ - keyid[0] = keyid[1] = 0; - main_keyid[0] = main_keyid[1] = 0; - revkeys = NULL; - knode = NULL; - key_seen = got_key = 0; - - *r_knode = NULL; - rc = CDK_EOF; - while (!cdk_stream_eof(inp)) { - cdk_pkt_new(&pkt); - old_off = cdk_stream_tell(inp); - rc = cdk_pkt_read(inp, pkt, public); - if (rc) { - cdk_pkt_release(pkt); - if (rc == CDK_EOF) - break; - else { /* Release all packets we reached so far. */ - _cdk_log_debug - ("keydb_get_keyblock: error %d\n", rc); - cdk_kbnode_release(knode); - gnutls_assert(); - return rc; - } - } - - if (pkt->pkttype == CDK_PKT_PUBLIC_KEY || - pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY || - pkt->pkttype == CDK_PKT_SECRET_KEY || - pkt->pkttype == CDK_PKT_SECRET_SUBKEY) { - if (key_seen - && (pkt->pkttype == CDK_PKT_PUBLIC_KEY - || pkt->pkttype == CDK_PKT_SECRET_KEY)) { - /* The next key starts here so set the file pointer - and leave the loop. */ - cdk_stream_seek(inp, old_off); - cdk_pkt_release(pkt); - break; - } - if (pkt->pkttype == CDK_PKT_PUBLIC_KEY || - pkt->pkttype == CDK_PKT_SECRET_KEY) { - _cdk_pkt_get_keyid(pkt, main_keyid); - key_seen = 1; - } else if (pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY || - pkt->pkttype == CDK_PKT_SECRET_SUBKEY) { - if (pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY) { - pkt->pkt.public_key-> - main_keyid[0] = main_keyid[0]; - pkt->pkt.public_key-> - main_keyid[1] = main_keyid[1]; - } else { - pkt->pkt.secret_key-> - main_keyid[0] = main_keyid[0]; - pkt->pkt.secret_key-> - main_keyid[1] = main_keyid[1]; - } - } - /* We save this for the signature */ - _cdk_pkt_get_keyid(pkt, keyid); - got_key = 1; - } else if (pkt->pkttype == CDK_PKT_USER_ID); - else if (pkt->pkttype == CDK_PKT_SIGNATURE) { - cdk_subpkt_t s; - - pkt->pkt.signature->key[0] = keyid[0]; - pkt->pkt.signature->key[1] = keyid[1]; - if (pkt->pkt.signature->sig_class == 0x1F && - pkt->pkt.signature->revkeys) - revkeys = pkt->pkt.signature->revkeys; - - s = cdk_subpkt_find(pkt->pkt.signature->hashed, - CDK_SIGSUBPKT_KEY_FLAGS); - if (s) { - unsigned int key_usage = - key_usage_to_cdk_usage(s->d[0]); - add_key_usage(knode, - pkt->pkt.signature->key, - key_usage); - } - } - node = cdk_kbnode_new(pkt); - if (!knode) - knode = node; - else - _cdk_kbnode_add(knode, node); - } - - if (got_key) { - keydb_merge_selfsig(knode, main_keyid); - rc = keydb_parse_allsigs(knode, NULL, 0); - if (revkeys) { - node = cdk_kbnode_find(knode, CDK_PKT_PUBLIC_KEY); - if (node) - node->pkt->pkt.public_key->revkeys = - revkeys; - } - } else - cdk_kbnode_release(knode); - *r_knode = got_key ? knode : NULL; - - /* It is possible that we are in an EOF condition after we - successfully read a keyblock. For example if the requested - key is the last in the file. */ - if (rc == CDK_EOF && got_key) - rc = 0; - return rc; -} - - -/* Return the type of the given data. In case it cannot be classified, - a substring search will be performed. */ -static int classify_data(const byte * buf, size_t len) -{ - int type; - unsigned int i; - - if (buf[0] == '0' && (buf[1] == 'x' || buf[1] == 'X')) { /* Skip hex prefix. */ - buf += 2; - len -= 2; - } - - /* The length of the data does not match either a keyid or a fingerprint. */ - if (len != 8 && len != 16 && len != 40) - return CDK_DBSEARCH_SUBSTR; - - for (i = 0; i < len; i++) { - if (!isxdigit(buf[i])) - return CDK_DBSEARCH_SUBSTR; - } - if (i != len) - return CDK_DBSEARCH_SUBSTR; - switch (len) { - case 8: - type = CDK_DBSEARCH_SHORT_KEYID; - break; - case 16: - type = CDK_DBSEARCH_KEYID; - break; - case 40: - type = CDK_DBSEARCH_FPR; - break; - default: - type = CDK_DBSEARCH_SUBSTR; - break; - } - - return type; -} - - -/** - * cdk_keydb_export: - * @hd: the keydb handle - * @out: the output stream - * @remusr: the list of key pattern to export - * - * Export a list of keys to the given output stream. - * Use string list with names for pattering searching. - * This procedure strips local signatures. - **/ -cdk_error_t -cdk_keydb_export(cdk_keydb_hd_t hd, cdk_stream_t out, cdk_strlist_t remusr) -{ - cdk_kbnode_t knode, node; - cdk_strlist_t r; - cdk_error_t rc; - int old_ctb; - cdk_keydb_search_t st; - - for (r = remusr; r; r = r->next) { - rc = cdk_keydb_search_start(&st, hd, CDK_DBSEARCH_AUTO, - r->d); - if (rc) { - gnutls_assert(); - return rc; - } - rc = cdk_keydb_search(st, hd, &knode); - cdk_keydb_search_release(st); - - if (rc) { - gnutls_assert(); - return rc; - } - - node = cdk_kbnode_find(knode, CDK_PKT_PUBLIC_KEY); - if (!node) { - gnutls_assert(); - return CDK_Error_No_Key; - } - - /* If the key is a version 3 key, use the old packet - format for the output. */ - if (node->pkt->pkt.public_key->version == 3) - old_ctb = 1; - else - old_ctb = 0; - - for (node = knode; node; node = node->next) { - /* No specified format; skip them */ - if (node->pkt->pkttype == CDK_PKT_RING_TRUST) - continue; - /* We never export local signed signatures */ - if (node->pkt->pkttype == CDK_PKT_SIGNATURE && - !node->pkt->pkt.signature->flags.exportable) - continue; - /* Filter out invalid signatures */ - if (node->pkt->pkttype == CDK_PKT_SIGNATURE && - (!KEY_CAN_SIGN - (node->pkt->pkt.signature->pubkey_algo))) - continue; - - /* Adjust the ctb flag if needed. */ - node->pkt->old_ctb = old_ctb; - rc = cdk_pkt_write(out, node->pkt); - if (rc) { - cdk_kbnode_release(knode); - gnutls_assert(); - return rc; - } - } - cdk_kbnode_release(knode); - knode = NULL; - } - return 0; -} - - -static cdk_packet_t find_key_packet(cdk_kbnode_t knode, int *r_is_sk) -{ - cdk_packet_t pkt; - - pkt = cdk_kbnode_find_packet(knode, CDK_PKT_PUBLIC_KEY); - if (!pkt) { - pkt = cdk_kbnode_find_packet(knode, CDK_PKT_SECRET_KEY); - if (r_is_sk) - *r_is_sk = pkt ? 1 : 0; - } - return pkt; -} - - -/* Return 1 if the is allowd in a key node. */ -static int is_key_node(cdk_kbnode_t node) -{ - switch (node->pkt->pkttype) { - case CDK_PKT_SIGNATURE: - case CDK_PKT_SECRET_KEY: - case CDK_PKT_PUBLIC_KEY: - case CDK_PKT_SECRET_SUBKEY: - case CDK_PKT_PUBLIC_SUBKEY: - case CDK_PKT_USER_ID: - case CDK_PKT_ATTRIBUTE: - return 1; - - default: - return 0; - } - - return 0; -} - - -cdk_error_t cdk_keydb_import(cdk_keydb_hd_t hd, cdk_kbnode_t knode) -{ - cdk_kbnode_t node, chk; - cdk_packet_t pkt; - cdk_stream_t out; - cdk_error_t rc; - u32 keyid[2]; - - if (!hd || !knode) { - gnutls_assert(); - return CDK_Inv_Value; - } - - pkt = find_key_packet(knode, NULL); - if (!pkt) { - gnutls_assert(); - return CDK_Inv_Packet; - } - - _cdk_pkt_get_keyid(pkt, keyid); - chk = NULL; - cdk_keydb_get_bykeyid(hd, keyid, &chk); - if (chk) { /* FIXME: search for new signatures */ - cdk_kbnode_release(chk); - return 0; - } - - /* We append data to the stream so we need to close - the stream here to re-open it later. */ - if (hd->fp) { - cdk_stream_close(hd->fp); - hd->fp = NULL; - } - - rc = _cdk_stream_append(hd->name, &out); - if (rc) { - gnutls_assert(); - return rc; - } - - for (node = knode; node; node = node->next) { - if (node->pkt->pkttype == CDK_PKT_RING_TRUST) - continue; /* No uniformed syntax for this packet */ - if (node->pkt->pkttype == CDK_PKT_SIGNATURE && - !node->pkt->pkt.signature->flags.exportable) { - _cdk_log_debug - ("key db import: skip local signature\n"); - continue; - } - - if (!is_key_node(node)) { - _cdk_log_debug - ("key db import: skip invalid node of type %d\n", - node->pkt->pkttype); - continue; - } - - rc = cdk_pkt_write(out, node->pkt); - if (rc) { - cdk_stream_close(out); - gnutls_assert(); - return rc; - } - } - - cdk_stream_close(out); - hd->stats.new_keys++; - - return 0; -} - - -cdk_error_t -_cdk_keydb_check_userid(cdk_keydb_hd_t hd, u32 * keyid, const char *id) -{ - cdk_kbnode_t knode = NULL, unode = NULL; - cdk_error_t rc; - int check; - cdk_keydb_search_t st; - - if (!hd) { - gnutls_assert(); - return CDK_Inv_Value; - } - - rc = cdk_keydb_search_start(&st, hd, CDK_DBSEARCH_KEYID, keyid); - if (rc) { - gnutls_assert(); - return rc; - } - rc = cdk_keydb_search(st, hd, &knode); - cdk_keydb_search_release(st); - - if (rc) { - gnutls_assert(); - return rc; - } - - rc = cdk_keydb_search_start(&st, hd, CDK_DBSEARCH_EXACT, - (char *) id); - if (!rc) { - rc = cdk_keydb_search(st, hd, &unode); - cdk_keydb_search_release(st); - } - if (rc) { - cdk_kbnode_release(knode); - gnutls_assert(); - return rc; - } - - check = 0; - rc = cdk_keydb_search_start(&st, hd, CDK_DBSEARCH_KEYID, keyid); - if (rc) { - cdk_kbnode_release(knode); - gnutls_assert(); - return rc; - } - - if (unode && find_by_keyid(unode, st)) - check++; - cdk_keydb_search_release(st); - cdk_kbnode_release(unode); - - rc = cdk_keydb_search_start(&st, hd, CDK_DBSEARCH_EXACT, - (char *) id); - if (rc) { - cdk_kbnode_release(knode); - gnutls_assert(); - return rc; - } - - if (knode && find_by_pattern(knode, st)) - check++; - cdk_keydb_search_release(st); - cdk_kbnode_release(knode); - - return check == 2 ? 0 : CDK_Inv_Value; -} - - -/** - * cdk_keydb_check_sk: - * @hd: the key db handle - * @keyid: the 64-bit keyid - * - * Check if a secret key with the given key ID is available - * in the key database. - **/ -cdk_error_t cdk_keydb_check_sk(cdk_keydb_hd_t hd, u32 * keyid) -{ - cdk_stream_t db; - cdk_packet_t pkt; - cdk_error_t rc; - u32 kid[2]; - - if (!hd || !keyid) { - gnutls_assert(); - return CDK_Inv_Value; - } - if (!hd->secret) { - gnutls_assert(); - return CDK_Inv_Mode; - } - - rc = _cdk_keydb_open(hd, &db); - if (rc) { - gnutls_assert(); - return rc; - } - cdk_pkt_new(&pkt); - while (!cdk_pkt_read(db, pkt, 0)) { - if (pkt->pkttype != CDK_PKT_SECRET_KEY && - pkt->pkttype != CDK_PKT_SECRET_SUBKEY) { - cdk_pkt_free(pkt); - continue; - } - cdk_sk_get_keyid(pkt->pkt.secret_key, kid); - if (KEYID_CMP(kid, keyid)) { - cdk_pkt_release(pkt); - return 0; - } - cdk_pkt_free(pkt); - } - cdk_pkt_release(pkt); - gnutls_assert(); - return CDK_Error_No_Key; -} - - -/** - * cdk_listkey_start: - * @r_ctx: pointer to store the new context - * @db: the key database handle - * @patt: string pattern - * @fpatt: recipients from a stringlist to show - * - * Prepare a key listing with the given parameters. Two modes are supported. - * The first mode uses string pattern to determine if the key should be - * returned or not. The other mode uses a string list to request the key - * which should be listed. - **/ -cdk_error_t -cdk_listkey_start(cdk_listkey_t * r_ctx, cdk_keydb_hd_t db, - const char *patt, cdk_strlist_t fpatt) -{ - cdk_listkey_t ctx; - cdk_stream_t inp; - cdk_error_t rc; - - if (!r_ctx || !db) { - gnutls_assert(); - return CDK_Inv_Value; - } - if ((patt && fpatt) || (!patt && !fpatt)) { - gnutls_assert(); - return CDK_Inv_Mode; - } - rc = _cdk_keydb_open(db, &inp); - if (rc) { - gnutls_assert(); - return rc; - } - ctx = cdk_calloc(1, sizeof *ctx); - if (!ctx) { - gnutls_assert(); - return CDK_Out_Of_Core; - } - ctx->db = db; - ctx->inp = inp; - if (patt) { - ctx->u.patt = cdk_strdup(patt); - if (!ctx->u.patt) { - gnutls_assert(); - return CDK_Out_Of_Core; - } - } else if (fpatt) { - cdk_strlist_t l; - for (l = fpatt; l; l = l->next) - cdk_strlist_add(&ctx->u.fpatt, l->d); - } - ctx->type = patt ? 1 : 0; - ctx->init = 1; - *r_ctx = ctx; - return 0; -} - - -/** - * cdk_listkey_close: - * @ctx: the list key context - * - * Free the list key context. - **/ -void cdk_listkey_close(cdk_listkey_t ctx) -{ - if (!ctx) - return; - - if (ctx->type) - cdk_free(ctx->u.patt); - else - cdk_strlist_free(ctx->u.fpatt); - cdk_free(ctx); -} - - -/** - * cdk_listkey_next: - * @ctx: list key context - * @r_key: the pointer to the new key node object - * - * Retrieve the next key from the pattern of the key list context. - **/ -cdk_error_t cdk_listkey_next(cdk_listkey_t ctx, cdk_kbnode_t * ret_key) -{ - if (!ctx || !ret_key) { - gnutls_assert(); - return CDK_Inv_Value; - } - if (!ctx->init) { - gnutls_assert(); - return CDK_Inv_Mode; - } - - if (ctx->type && ctx->u.patt[0] == '*') - return cdk_keydb_get_keyblock(ctx->inp, ret_key, 1); - else if (ctx->type) { - cdk_kbnode_t node; - struct cdk_keydb_search_s ks; - cdk_error_t rc; - - for (;;) { - rc = cdk_keydb_get_keyblock(ctx->inp, &node, 1); - if (rc) { - gnutls_assert(); - return rc; - } - memset(&ks, 0, sizeof(ks)); - ks.type = CDK_DBSEARCH_SUBSTR; - ks.u.pattern = ctx->u.patt; - if (find_by_pattern(node, &ks)) { - *ret_key = node; - return 0; - } - cdk_kbnode_release(node); - node = NULL; - } - } else { - if (!ctx->t) - ctx->t = ctx->u.fpatt; - else if (ctx->t->next) - ctx->t = ctx->t->next; - else - return CDK_EOF; - return cdk_keydb_get_bypattern(ctx->db, ctx->t->d, - ret_key); - } - gnutls_assert(); - return CDK_General_Error; -} - - -int _cdk_keydb_is_secret(cdk_keydb_hd_t db) -{ - return db->secret; -} diff --git a/lib/opencdk/keydb.h b/lib/opencdk/keydb.h deleted file mode 100644 index a7a12c1e85..0000000000 --- a/lib/opencdk/keydb.h +++ /dev/null @@ -1,68 +0,0 @@ -/* keydb.h - Key database routines - * Copyright (C) 2002-2012 Free Software Foundation, Inc. - * - * Author: Timo Schulz - * - * This file is part of OpenCDK. - * - * The OpenCDK 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -/* Internal key index structure. */ -struct key_idx_s { - off_t offset; - u32 keyid[2]; - byte fpr[KEY_FPR_LEN]; -}; -typedef struct key_idx_s *key_idx_t; - -/* Internal key cache to associate a key with an file offset. */ -struct key_table_s { - struct key_table_s *next; - off_t offset; -}; -typedef struct key_table_s *key_table_t; - -typedef struct cdk_keydb_search_s { - off_t off; /* last file offset */ - union { - char *pattern; /* A search is performed by pattern. */ - u32 keyid[2]; /* A search by keyid. */ - byte fpr[KEY_FPR_LEN]; /* A search by fingerprint. */ - } u; - int type; - struct key_table_s *cache; - size_t ncache; - unsigned int no_cache:1; /* disable the index cache. */ - - cdk_stream_t idx; - char *idx_name; /* name of the index file or NULL. */ - -} cdk_keydb_search_s; - -/* Internal key database handle. */ -struct cdk_keydb_hd_s { - int type; /* type of the key db handle. */ - int fp_ref; /* 1=means it is a reference and shall not be closed. */ - cdk_stream_t fp; - char *name; /* name of the underlying file or NULL. */ - unsigned int secret:1; /* contain secret keys. */ - unsigned int isopen:1; /* the underlying stream is opened. */ - - /* structure to store some stats about the keydb. */ - struct { - size_t new_keys; /* amount of new keys that were imported. */ - } stats; -}; diff --git a/lib/opencdk/literal.c b/lib/opencdk/literal.c deleted file mode 100644 index 7756bb33c7..0000000000 --- a/lib/opencdk/literal.c +++ /dev/null @@ -1,309 +0,0 @@ -/* literal.c - Literal packet filters - * Copyright (C) 2002-2012 Free Software Foundation, Inc. - * - * Author: Timo Schulz - * - * This file is part of OpenCDK. - * - * The OpenCDK 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include <opencdk.h> -#include <main.h> -#include <filters.h> -#include "gnutls_int.h" -#include <str.h> - - -/* Duplicate the string @s but strip of possible - relative folder names of it. */ -static char *dup_trim_filename(const char *s) -{ - char *p = NULL; - - p = strrchr(s, '/'); - if (!p) - p = strrchr(s, '\\'); - if (!p) - return cdk_strdup(s); - return cdk_strdup(p + 1); -} - - -static cdk_error_t literal_decode(void *data, FILE * in, FILE * out) -{ - literal_filter_t *pfx = data; - cdk_stream_t si, so; - cdk_packet_t pkt; - cdk_pkt_literal_t pt; - byte buf[BUFSIZE]; - ssize_t nread; - int bufsize; - cdk_error_t rc; - - _cdk_log_debug("literal filter: decode\n"); - - if (!pfx || !in || !out) - return CDK_Inv_Value; - - rc = _cdk_stream_fpopen(in, STREAMCTL_READ, &si); - if (rc) - return rc; - - cdk_pkt_new(&pkt); - rc = cdk_pkt_read(si, pkt, 1); - if (rc || pkt->pkttype != CDK_PKT_LITERAL) { - cdk_pkt_release(pkt); - cdk_stream_close(si); - return !rc ? CDK_Inv_Packet : rc; - } - - rc = _cdk_stream_fpopen(out, STREAMCTL_WRITE, &so); - if (rc) { - cdk_pkt_release(pkt); - cdk_stream_close(si); - return rc; - } - - pt = pkt->pkt.literal; - pfx->mode = pt->mode; - - if (pfx->filename && pt->namelen > 0) { - /* The name in the literal packet is more authorative. */ - cdk_free(pfx->filename); - pfx->filename = dup_trim_filename(pt->name); - } else if (!pfx->filename && pt->namelen > 0) - pfx->filename = dup_trim_filename(pt->name); - else if (!pt->namelen && !pfx->filename && pfx->orig_filename) { - /* In this case, we need to derrive the output file name - from the original name and cut off the OpenPGP extension. - If this is not possible, we return an error. */ - if (!stristr(pfx->orig_filename, ".gpg") && - !stristr(pfx->orig_filename, ".pgp") && - !stristr(pfx->orig_filename, ".asc")) { - cdk_pkt_release(pkt); - cdk_stream_close(si); - cdk_stream_close(so); - _cdk_log_debug - ("literal filter: no file name and no PGP extension\n"); - return CDK_Inv_Mode; - } - _cdk_log_debug - ("literal filter: derrive file name from original\n"); - pfx->filename = dup_trim_filename(pfx->orig_filename); - pfx->filename[strlen(pfx->filename) - 4] = '\0'; - } - - while (!feof(in)) { - _cdk_log_debug("literal_decode: part on %d size %lu\n", - (int) pfx->blkmode.on, - (unsigned long) pfx->blkmode.size); - if (pfx->blkmode.on) - bufsize = pfx->blkmode.size; - else - bufsize = pt->len < DIM(buf) ? pt->len : DIM(buf); - nread = cdk_stream_read(pt->buf, buf, bufsize); - if (nread == EOF) { - rc = CDK_File_Error; - break; - } - if (pfx->md_initialized) - _gnutls_hash(&pfx->md, buf, nread); - cdk_stream_write(so, buf, nread); - pt->len -= nread; - if (pfx->blkmode.on) { - pfx->blkmode.size = - _cdk_pkt_read_len(in, &pfx->blkmode.on); - if ((ssize_t) pfx->blkmode.size == EOF) - return CDK_Inv_Packet; - } - if (pt->len <= 0 && !pfx->blkmode.on) - break; - } - - cdk_stream_close(si); - cdk_stream_close(so); - cdk_pkt_release(pkt); - return rc; -} - - -static char intmode_to_char(int mode) -{ - switch (mode) { - case CDK_LITFMT_BINARY: - return 'b'; - case CDK_LITFMT_TEXT: - return 't'; - case CDK_LITFMT_UNICODE: - return 'u'; - default: - return 'b'; - } - - return 'b'; -} - - -static cdk_error_t literal_encode(void *data, FILE * in, FILE * out) -{ - literal_filter_t *pfx = data; - cdk_pkt_literal_t pt; - cdk_stream_t si; - cdk_packet_t pkt; - size_t filelen; - cdk_error_t rc; - - _cdk_log_debug("literal filter: encode\n"); - - if (!pfx || !in || !out) - return CDK_Inv_Value; - if (!pfx->filename) { - pfx->filename = cdk_strdup("_CONSOLE"); - if (!pfx->filename) - return CDK_Out_Of_Core; - } - - rc = _cdk_stream_fpopen(in, STREAMCTL_READ, &si); - if (rc) - return rc; - - filelen = strlen(pfx->filename); - cdk_pkt_new(&pkt); - pt = pkt->pkt.literal = cdk_calloc(1, sizeof *pt + filelen); - if (pt == NULL) { - cdk_pkt_release(pkt); - cdk_stream_close(si); - return gnutls_assert_val(CDK_Out_Of_Core); - } - - pt->name = (char *) pt + sizeof(*pt); - - memcpy(pt->name, pfx->filename, filelen); - pt->namelen = filelen; - pt->name[pt->namelen] = '\0'; - pt->timestamp = (u32) gnutls_time(NULL); - pt->mode = intmode_to_char(pfx->mode); - pt->len = cdk_stream_get_length(si); - pt->buf = si; - pkt->old_ctb = 1; - pkt->pkttype = CDK_PKT_LITERAL; - rc = _cdk_pkt_write_fp(out, pkt); - - cdk_pkt_release(pkt); - cdk_stream_close(si); - return rc; -} - - -int _cdk_filter_literal(void *data, int ctl, FILE * in, FILE * out) -{ - if (ctl == STREAMCTL_READ) - return literal_decode(data, in, out); - else if (ctl == STREAMCTL_WRITE) - return literal_encode(data, in, out); - else if (ctl == STREAMCTL_FREE) { - literal_filter_t *pfx = data; - if (pfx) { - _cdk_log_debug("free literal filter\n"); - cdk_free(pfx->filename); - pfx->filename = NULL; - cdk_free(pfx->orig_filename); - pfx->orig_filename = NULL; - return 0; - } - } - return CDK_Inv_Mode; -} - -/* Remove all trailing white spaces from the string. */ -static void _cdk_trim_string(char *s) -{ - int len = strlen(s); - int i; - - for (i=len-1;i>=0;i--) { - if ((s[i] == '\t' || s[i] == '\r' || s[i] == '\n' || s[i] == ' ')) { - s[i] = 0; - } else { - break; - } - } -} - -static int text_encode(void *data, FILE * in, FILE * out) -{ - const char *s; - char buf[2048]; - - if (!in || !out) - return CDK_Inv_Value; - - /* FIXME: This code does not work for very long lines. */ - while (!feof(in)) { - /* give space for trim_string \r\n */ - s = fgets(buf, DIM(buf) - 3, in); - if (!s) - break; - _cdk_trim_string(buf); - _gnutls_str_cat(buf, sizeof(buf), "\r\n"); - fwrite(buf, 1, strlen(buf), out); - } - - return 0; -} - - -static int text_decode(void *data, FILE * in, FILE * out) -{ - text_filter_t *tfx = data; - const char *s; - char buf[2048]; - - if (!tfx || !in || !out) - return CDK_Inv_Value; - - while (!feof(in)) { - s = fgets(buf, DIM(buf) - 1, in); - if (!s) - break; - _cdk_trim_string(buf); - fwrite(buf, 1, strlen(buf), out); - fwrite(tfx->lf, 1, strlen(tfx->lf), out); - } - - return 0; -} - - -int _cdk_filter_text(void *data, int ctl, FILE * in, FILE * out) -{ - if (ctl == STREAMCTL_READ) - return text_encode(data, in, out); - else if (ctl == STREAMCTL_WRITE) - return text_decode(data, in, out); - else if (ctl == STREAMCTL_FREE) { - text_filter_t *tfx = data; - if (tfx) { - _cdk_log_debug("free text filter\n"); - tfx->lf = NULL; - } - } - return CDK_Inv_Mode; -} diff --git a/lib/opencdk/main.h b/lib/opencdk/main.h deleted file mode 100644 index d95f277862..0000000000 --- a/lib/opencdk/main.h +++ /dev/null @@ -1,176 +0,0 @@ -/* main.h - * Copyright (C) 2002-2012 Free Software Foundation, Inc. - * - * Author: Timo Schulz - * - * This file is part of OpenCDK. - * - * The OpenCDK 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef CDK_MAIN_H -#define CDK_MAIN_H - -#include "types.h" - -#define _cdk_log_debug _gnutls_hard_log -#define _cdk_log_info _gnutls_debug_log -#define _cdk_get_log_level() _gnutls_log_level - -#define cdk_malloc gnutls_malloc -#define cdk_free gnutls_free -#define cdk_calloc gnutls_calloc -#define cdk_realloc gnutls_realloc_fast -#define cdk_strdup gnutls_strdup -#define cdk_salloc gnutls_secure_calloc - -#define map_gnutls_error _cdk_map_gnutls_error - -cdk_error_t map_gnutls_error(int err); - -/* The general size of a buffer for the variou modules. */ -#define BUFSIZE 8192 - -/* This is the default block size for the partial length packet mode. */ -#define DEF_BLOCKSIZE 8192 -#define DEF_BLOCKBITS 13 /* 2^13 = 8192 */ - -/* For now SHA-1 is used to create fingerprint for keys. - But if this will ever change, it is a good idea to - have a constant for it to avoid to change it in all files. */ -#define KEY_FPR_LEN 20 - -#include "context.h" - -/* The maximal amount of bits a multi precsion integer can have. */ -#define MAX_MPI_BITS 16384 -#define MAX_MPI_BYTES (MAX_MPI_BITS/8) - - -/* Because newer DSA variants are not limited to SHA-1, we must consider - that SHA-512 is used and increase the buffer size of the digest. */ -#define MAX_DIGEST_LEN 64 - -/* Helper to find out if the signature were made over a user ID - or if the signature revokes a previous user ID. */ -#define IS_UID_SIG(s) (((s)->sig_class & ~3) == 0x10) -#define IS_UID_REV(s) ((s)->sig_class == 0x30) - -/* Helper to find out if a key has the requested capability. */ -#define KEY_CAN_ENCRYPT(a) ((_cdk_pk_algo_usage ((a))) & CDK_KEY_USG_ENCR) -#define KEY_CAN_SIGN(a) ((_cdk_pk_algo_usage ((a))) & CDK_KEY_USG_SIGN) -#define KEY_CAN_AUTH(a) ((_cdk_pk_algo_usage ((a))) & CDK_KEY_USG_AUTH) - -#define DEBUG_PKT 0 - -/*-- main.c --*/ -char *_cdk_passphrase_get(cdk_ctx_t hd, const char *prompt); - -/*-- misc.c --*/ -int _cdk_check_args(int overwrite, const char *in, const char *out); -u32 _cdk_buftou32(const byte * buf); -void _cdk_u32tobuf(u32 u, byte * buf); -const char *_cdk_memistr(const char *buf, size_t buflen, const char *sub); -FILE *_cdk_tmpfile(void); - -/* Helper to provide case insentensive strstr version. */ -#define stristr(haystack, needle) \ - _cdk_memistr((haystack), strlen (haystack), (needle)) - -/*-- proc-packet.c --*/ -cdk_error_t _cdk_pkt_write2(cdk_stream_t out, int pkttype, void *pktctx); - -/*-- pubkey.c --*/ -u32 _cdk_pkt_get_keyid(cdk_packet_t pkt, u32 * keyid); -cdk_error_t _cdk_pkt_get_fingerprint(cdk_packet_t pkt, byte * fpr); -int _cdk_pk_algo_usage(int algo); -int _cdk_pk_test_algo(int algo, unsigned int usage); -int _cdk_sk_get_csum(cdk_pkt_seckey_t sk); - -/*-- new-packet.c --*/ -byte *_cdk_subpkt_get_array(cdk_subpkt_t s, int count, size_t * r_nbytes); -cdk_error_t _cdk_subpkt_copy(cdk_subpkt_t * r_dst, cdk_subpkt_t src); -void _cdk_pkt_detach_free(cdk_packet_t pkt, int *r_pkttype, void **ctx); - -/*-- sig-check.c --*/ -cdk_error_t _cdk_sig_check(cdk_pkt_pubkey_t pk, cdk_pkt_signature_t sig, - digest_hd_st * digest, int *r_expired); -cdk_error_t _cdk_hash_sig_data(cdk_pkt_signature_t sig, digest_hd_st * hd); -cdk_error_t _cdk_hash_userid(cdk_pkt_userid_t uid, int sig_version, - digest_hd_st * md); -cdk_error_t _cdk_hash_pubkey(cdk_pkt_pubkey_t pk, digest_hd_st * md, - int use_fpr); -cdk_error_t _cdk_pk_check_sig(cdk_keydb_hd_t hd, cdk_kbnode_t knode, - cdk_kbnode_t snode, int *is_selfsig, - char **ret_uid); - -/*-- kbnode.c --*/ -void _cdk_kbnode_add(cdk_kbnode_t root, cdk_kbnode_t node); -void _cdk_kbnode_clone(cdk_kbnode_t node); - -/*-- sesskey.c --*/ -cdk_error_t _cdk_sk_unprotect_auto(cdk_ctx_t hd, cdk_pkt_seckey_t sk); - -/*-- keydb.c --*/ -int _cdk_keydb_is_secret(cdk_keydb_hd_t db); -cdk_error_t _cdk_keydb_get_pk_byusage(cdk_keydb_hd_t hd, const char *name, - cdk_pkt_pubkey_t * ret_pk, - int usage); -cdk_error_t _cdk_keydb_get_sk_byusage(cdk_keydb_hd_t hd, const char *name, - cdk_pkt_seckey_t * ret_sk, - int usage); -cdk_error_t _cdk_keydb_check_userid(cdk_keydb_hd_t hd, u32 * keyid, - const char *id); - -/*-- sign.c --*/ -int _cdk_sig_hash_for(cdk_pkt_pubkey_t pk); -cdk_error_t _cdk_sig_create(cdk_pkt_pubkey_t pk, cdk_pkt_signature_t sig); -cdk_error_t _cdk_sig_complete(cdk_pkt_signature_t sig, cdk_pkt_seckey_t sk, - digest_hd_st * hd); - -/*-- stream.c --*/ -void _cdk_stream_set_compress_algo(cdk_stream_t s, int algo); -cdk_error_t _cdk_stream_open_mode(const char *file, const char *mode, - cdk_stream_t * ret_s); -void *_cdk_stream_get_uint8_t(cdk_stream_t s, int fid); -const char *_cdk_stream_get_fname(cdk_stream_t s); -FILE *_cdk_stream_get_fp(cdk_stream_t s); -int _cdk_stream_gets(cdk_stream_t s, char *buf, size_t count); -cdk_error_t _cdk_stream_append(const char *file, cdk_stream_t * ret_s); -int _cdk_stream_get_errno(cdk_stream_t s); -cdk_error_t _cdk_stream_set_blockmode(cdk_stream_t s, size_t nbytes); -int _cdk_stream_get_blockmode(cdk_stream_t s); -int _cdk_stream_puts(cdk_stream_t s, const char *buf); -cdk_error_t _cdk_stream_fpopen(FILE * fp, unsigned write_mode, - cdk_stream_t * ret_out); - - -/*-- read-packet.c --*/ -size_t _cdk_pkt_read_len(FILE * inp, size_t * ret_partial); - -/*-- write-packet.c --*/ -cdk_error_t _cdk_pkt_write_fp(FILE * out, cdk_packet_t pkt); - -/*-- seskey.c --*/ -cdk_error_t _cdk_s2k_copy(cdk_s2k_t * r_dst, cdk_s2k_t src); - -#define _cdk_pub_algo_to_pgp(algo) (algo) -#define _pgp_pub_algo_to_cdk(algo) (algo) -int _gnutls_hash_algo_to_pgp(int algo); -int _pgp_hash_algo_to_gnutls(int algo); -int _gnutls_cipher_to_pgp(int cipher); -int _pgp_cipher_to_gnutls(int cipher); - -#endif /* CDK_MAIN_H */ diff --git a/lib/opencdk/misc.c b/lib/opencdk/misc.c deleted file mode 100644 index 7c411688a1..0000000000 --- a/lib/opencdk/misc.c +++ /dev/null @@ -1,301 +0,0 @@ -/* misc.c - * Copyright (C) 1998-2012 Free Software Foundation, Inc. - * - * Author: Timo Schulz - * - * This file is part of OpenCDK. - * - * The OpenCDK 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include <string.h> -#include <ctype.h> -#include <sys/stat.h> -#include <c-ctype.h> -#include <opencdk.h> -#include <main.h> -#include <random.h> -#include "gnutls_int.h" -#include <str.h> - - -u32 _cdk_buftou32(const byte * buf) -{ - u32 u; - - if (!buf) - return 0; - u = ((u32)buf[0]) << 24; - u |= buf[1] << 16; - u |= buf[2] << 8; - u |= buf[3]; - return u; -} - - -void _cdk_u32tobuf(u32 u, byte * buf) -{ - if (!buf) - return; - buf[0] = u >> 24; - buf[1] = u >> 16; - buf[2] = u >> 8; - buf[3] = u; -} - -/** - * cdk_strlist_free: - * @sl: the string list - * - * Release the string list object. - **/ -void cdk_strlist_free(cdk_strlist_t sl) -{ - cdk_strlist_t sl2; - - for (; sl; sl = sl2) { - sl2 = sl->next; - cdk_free(sl); - } -} - - -/** - * cdk_strlist_add: - * @list: destination string list - * @string: the string to add - * - * Add the given list to the string list. - **/ -cdk_strlist_t cdk_strlist_add(cdk_strlist_t * list, const char *string) -{ - if (!string) - return NULL; - - cdk_strlist_t sl; - int string_size = strlen(string); - - sl = cdk_calloc(1, sizeof *sl + string_size + 2); - if (!sl) - return NULL; - sl->d = (char *) sl + sizeof(*sl); - memcpy(sl->d, string, string_size + 1); - sl->next = *list; - *list = sl; - return sl; -} - -const char *_cdk_memistr(const char *buf, size_t buflen, const char *sub) -{ - const byte *t, *s; - size_t n; - - for (t = (byte *) buf, n = buflen, s = (byte *) sub; n; t++, n--) { - if (c_toupper(*t) == c_toupper(*s)) { - for (buf = (char *) t++, buflen = n--, s++; - n && c_toupper(*t) == c_toupper((byte) * s); - t++, s++, n--); - if (!*s) - return buf; - t = (byte *) buf; - n = buflen; - s = (byte *) sub; - } - } - - return NULL; -} - -cdk_error_t _cdk_map_gnutls_error(int err) -{ - switch (err) { - case 0: - return CDK_Success; - case GNUTLS_E_INVALID_REQUEST: - return CDK_Inv_Value; - default: - return CDK_General_Error; - } -} - - -int _cdk_check_args(int overwrite, const char *in, const char *out) -{ - struct stat stbuf; - - if (!in || !out) - return CDK_Inv_Value; - if (strlen(in) == strlen(out) && strcmp(in, out) == 0) - return CDK_Inv_Mode; - if (!overwrite && !stat(out, &stbuf)) - return CDK_Inv_Mode; - return 0; -} - -#ifdef _WIN32 -#include <io.h> -#include <fcntl.h> - -FILE *_cdk_tmpfile(void) -{ - /* Because the tmpfile() version of wine is not really useful, - we implement our own version to avoid problems with 'make check'. */ - static const char *letters = "abcdefghijklmnopqrstuvwxyz"; - unsigned char buf[512], rnd[24]; - FILE *fp; - int fd, i; - - gnutls_rnd(GNUTLS_RND_NONCE, rnd, DIM(rnd)); - for (i = 0; i < DIM(rnd) - 1; i++) { - char c = letters[(unsigned char) rnd[i] % 26]; - rnd[i] = c; - } - rnd[DIM(rnd) - 1] = 0; - if (!GetTempPath(464, buf)) - return NULL; - _gnutls_str_cat(buf, sizeof(buf), "_cdk_"); - _gnutls_str_cat(buf, sizeof(buf), rnd); - - /* We need to make sure the file will be deleted when it is closed. */ - fd = _open(buf, _O_CREAT | _O_EXCL | _O_TEMPORARY | - _O_RDWR | _O_BINARY, _S_IREAD | _S_IWRITE); - if (fd == -1) - return NULL; - fp = fdopen(fd, "w+b"); - if (fp != NULL) - return fp; - _close(fd); - return NULL; -} -#else -FILE *_cdk_tmpfile(void) -{ - return tmpfile(); -} -#endif - -int _gnutls_hash_algo_to_pgp(int algo) -{ - switch (algo) { - case GNUTLS_DIG_MD5: - return 0x01; - case GNUTLS_DIG_MD2: - return 0x05; - case GNUTLS_DIG_SHA1: - return 0x02; - case GNUTLS_DIG_RMD160: - return 0x03; - case GNUTLS_DIG_SHA256: - return 0x08; - case GNUTLS_DIG_SHA384: - return 0x09; - case GNUTLS_DIG_SHA512: - return 0x0A; - case GNUTLS_DIG_SHA224: - return 0x0B; - default: - gnutls_assert(); - return 0x00; - } -} - -int _pgp_hash_algo_to_gnutls(int algo) -{ - switch (algo) { - case 0x01: - return GNUTLS_DIG_MD5; - case 0x02: - return GNUTLS_DIG_SHA1; - case 0x03: - return GNUTLS_DIG_RMD160; - case 0x05: - return GNUTLS_DIG_MD2; - case 0x08: - return GNUTLS_DIG_SHA256; - case 0x09: - return GNUTLS_DIG_SHA384; - case 0x0A: - return GNUTLS_DIG_SHA512; - case 0x0B: - return GNUTLS_DIG_SHA224; - default: - gnutls_assert(); - return GNUTLS_DIG_NULL; - } -} - -int _pgp_cipher_to_gnutls(int cipher) -{ - switch (cipher) { - case 0: - return GNUTLS_CIPHER_NULL; - case 1: - return GNUTLS_CIPHER_IDEA_PGP_CFB; - case 2: - return GNUTLS_CIPHER_3DES_PGP_CFB; - case 3: - return GNUTLS_CIPHER_CAST5_PGP_CFB; - case 4: - return GNUTLS_CIPHER_BLOWFISH_PGP_CFB; - case 5: - return GNUTLS_CIPHER_SAFER_SK128_PGP_CFB; - case 7: - return GNUTLS_CIPHER_AES128_PGP_CFB; - case 8: - return GNUTLS_CIPHER_AES192_PGP_CFB; - case 9: - return GNUTLS_CIPHER_AES256_PGP_CFB; - case 10: - return GNUTLS_CIPHER_TWOFISH_PGP_CFB; - - default: - gnutls_assert(); - _gnutls_debug_log("Unknown openpgp cipher %u\n", cipher); - return GNUTLS_CIPHER_UNKNOWN; - } -} - -int _gnutls_cipher_to_pgp(int cipher) -{ - switch (cipher) { - case GNUTLS_CIPHER_NULL: - return 0; - case GNUTLS_CIPHER_IDEA_PGP_CFB: - return 1; - case GNUTLS_CIPHER_3DES_PGP_CFB: - return 2; - case GNUTLS_CIPHER_CAST5_PGP_CFB: - return 3; - case GNUTLS_CIPHER_BLOWFISH_PGP_CFB: - return 4; - case GNUTLS_CIPHER_SAFER_SK128_PGP_CFB: - return 5; - case GNUTLS_CIPHER_AES128_PGP_CFB: - return 7; - case GNUTLS_CIPHER_AES192_PGP_CFB: - return 8; - case GNUTLS_CIPHER_AES256_PGP_CFB: - return 9; - case GNUTLS_CIPHER_TWOFISH_PGP_CFB: - return 10; - default: - gnutls_assert(); - return 0; - } -} diff --git a/lib/opencdk/new-packet.c b/lib/opencdk/new-packet.c deleted file mode 100644 index 1b35ef657f..0000000000 --- a/lib/opencdk/new-packet.c +++ /dev/null @@ -1,799 +0,0 @@ -/* new-packet.c - packet handling (freeing, copying, ...) - * Copyright (C) 2001-2012 Free Software Foundation, Inc. - * - * Author: Timo Schulz - * - * This file is part of OpenCDK. - * - * The OpenCDK 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <string.h> -#include <stdio.h> - -#include "opencdk.h" -#include "main.h" -#include "packet.h" - - -/* Release an array of MPI values. */ -void _cdk_free_mpibuf(size_t n, bigint_t * array) -{ - while (n--) { - _gnutls_mpi_release(&array[n]); - } -} - - -/** - * cdk_pkt_new: - * @r_pkt: the new packet - * - * Allocate a new packet. - **/ -cdk_error_t cdk_pkt_new(cdk_packet_t * r_pkt) -{ - cdk_packet_t pkt; - - if (!r_pkt) - return CDK_Inv_Value; - pkt = cdk_calloc(1, sizeof *pkt); - if (!pkt) - return CDK_Out_Of_Core; - *r_pkt = pkt; - return 0; -} - - -static void free_pubkey_enc(cdk_pkt_pubkey_enc_t enc) -{ - size_t nenc; - - if (!enc) - return; - - nenc = cdk_pk_get_nenc(enc->pubkey_algo); - _cdk_free_mpibuf(nenc, enc->mpi); - cdk_free(enc); -} - - -static void free_literal(cdk_pkt_literal_t pt) -{ - if (!pt) - return; - /* The buffer which is referenced in this packet is closed - elsewhere. To close it here would cause a double close. */ - cdk_free(pt); -} - - -void _cdk_free_userid(cdk_pkt_userid_t uid) -{ - if (!uid) - return; - - cdk_free(uid->prefs); - uid->prefs = NULL; - cdk_free(uid->attrib_img); - uid->attrib_img = NULL; - cdk_free(uid); -} - - -void _cdk_free_signature(cdk_pkt_signature_t sig) -{ - cdk_desig_revoker_t r; - size_t nsig; - - if (!sig) - return; - - nsig = cdk_pk_get_nsig(sig->pubkey_algo); - _cdk_free_mpibuf(nsig, sig->mpi); - - cdk_subpkt_free(sig->hashed); - sig->hashed = NULL; - cdk_subpkt_free(sig->unhashed); - sig->unhashed = NULL; - while (sig->revkeys) { - r = sig->revkeys->next; - cdk_free(sig->revkeys); - sig->revkeys = r; - } - cdk_free(sig); -} - - -void cdk_pk_release(cdk_pubkey_t pk) -{ - size_t npkey; - - if (!pk) - return; - - npkey = cdk_pk_get_npkey(pk->pubkey_algo); - _cdk_free_userid(pk->uid); - pk->uid = NULL; - cdk_free(pk->prefs); - pk->prefs = NULL; - _cdk_free_mpibuf(npkey, pk->mpi); - cdk_free(pk); -} - - -void cdk_sk_release(cdk_seckey_t sk) -{ - size_t nskey; - - if (!sk) - return; - - nskey = cdk_pk_get_nskey(sk->pubkey_algo); - _cdk_free_mpibuf(nskey, sk->mpi); - cdk_free(sk->encdata); - sk->encdata = NULL; - cdk_pk_release(sk->pk); - sk->pk = NULL; - cdk_s2k_free(sk->protect.s2k); - sk->protect.s2k = NULL; - cdk_free(sk); -} - - -/* Detach the openpgp packet from the packet structure - and release the packet structure itself. */ -void _cdk_pkt_detach_free(cdk_packet_t pkt, int *r_pkttype, void **ctx) -{ - /* For now we just allow this for keys. */ - switch (pkt->pkttype) { - case CDK_PKT_PUBLIC_KEY: - case CDK_PKT_PUBLIC_SUBKEY: - *ctx = pkt->pkt.public_key; - break; - - case CDK_PKT_SECRET_KEY: - case CDK_PKT_SECRET_SUBKEY: - *ctx = pkt->pkt.secret_key; - break; - - default: - *r_pkttype = 0; - return; - } - - /* The caller might expect a specific packet type and - is not interested to store it for later use. */ - if (r_pkttype) - *r_pkttype = pkt->pkttype; - - cdk_free(pkt); -} - - -void cdk_pkt_free(cdk_packet_t pkt) -{ - if (!pkt) - return; - - switch (pkt->pkttype) { - case CDK_PKT_ATTRIBUTE: - case CDK_PKT_USER_ID: - _cdk_free_userid(pkt->pkt.user_id); - break; - case CDK_PKT_PUBLIC_KEY: - case CDK_PKT_PUBLIC_SUBKEY: - cdk_pk_release(pkt->pkt.public_key); - break; - case CDK_PKT_SECRET_KEY: - case CDK_PKT_SECRET_SUBKEY: - cdk_sk_release(pkt->pkt.secret_key); - break; - case CDK_PKT_SIGNATURE: - _cdk_free_signature(pkt->pkt.signature); - break; - case CDK_PKT_PUBKEY_ENC: - free_pubkey_enc(pkt->pkt.pubkey_enc); - break; - case CDK_PKT_MDC: - cdk_free(pkt->pkt.mdc); - break; - case CDK_PKT_ONEPASS_SIG: - cdk_free(pkt->pkt.onepass_sig); - break; - case CDK_PKT_LITERAL: - free_literal(pkt->pkt.literal); - break; - case CDK_PKT_COMPRESSED: - cdk_free(pkt->pkt.compressed); - break; - default: - break; - } - - /* Reset the packet type to avoid, when cdk_pkt_release() will be - used, that the second cdk_pkt_free() call will double free the data. */ - pkt->pkttype = 0; -} - - -/** - * cdk_pkt_release: - * @pkt: the packet - * - * Free the contents of the given package and - * release the memory of the structure. - **/ -void cdk_pkt_release(cdk_packet_t pkt) -{ - if (!pkt) - return; - cdk_pkt_free(pkt); - cdk_free(pkt); -} - - -/** - * cdk_pkt_alloc: - * @r_pkt: output is the new packet - * @pkttype: the requested packet type - * - * Allocate a new packet structure with the given packet type. - **/ -cdk_error_t cdk_pkt_alloc(cdk_packet_t * r_pkt, cdk_packet_type_t pkttype) -{ - cdk_packet_t pkt; - int rc; - - if (!r_pkt) - return CDK_Inv_Value; - - rc = cdk_pkt_new(&pkt); - if (rc) - return rc; - - switch (pkttype) { - case CDK_PKT_USER_ID: - pkt->pkt.user_id = cdk_calloc(1, sizeof *pkt->pkt.user_id); - if (!pkt->pkt.user_id) - return CDK_Out_Of_Core; - pkt->pkt.user_id->name = NULL; - break; - - case CDK_PKT_PUBLIC_KEY: - case CDK_PKT_PUBLIC_SUBKEY: - pkt->pkt.public_key = - cdk_calloc(1, sizeof *pkt->pkt.public_key); - if (!pkt->pkt.public_key) - return CDK_Out_Of_Core; - break; - - case CDK_PKT_SECRET_KEY: - case CDK_PKT_SECRET_SUBKEY: - pkt->pkt.secret_key = - cdk_calloc(1, sizeof *pkt->pkt.secret_key); - if (!pkt->pkt.secret_key) - return CDK_Out_Of_Core; - - pkt->pkt.secret_key->pk = - cdk_calloc(1, sizeof *pkt->pkt.secret_key->pk); - if (!pkt->pkt.secret_key->pk) { - cdk_free(pkt->pkt.secret_key); - pkt->pkt.secret_key = NULL; - return CDK_Out_Of_Core; - } - break; - - case CDK_PKT_SIGNATURE: - pkt->pkt.signature = - cdk_calloc(1, sizeof *pkt->pkt.signature); - if (!pkt->pkt.signature) - return CDK_Out_Of_Core; - break; - - case CDK_PKT_PUBKEY_ENC: - pkt->pkt.pubkey_enc = - cdk_calloc(1, sizeof *pkt->pkt.pubkey_enc); - if (!pkt->pkt.pubkey_enc) - return CDK_Out_Of_Core; - break; - - case CDK_PKT_MDC: - pkt->pkt.mdc = cdk_calloc(1, sizeof *pkt->pkt.mdc); - if (!pkt->pkt.mdc) - return CDK_Out_Of_Core; - break; - - case CDK_PKT_ONEPASS_SIG: - pkt->pkt.onepass_sig = - cdk_calloc(1, sizeof *pkt->pkt.onepass_sig); - if (!pkt->pkt.onepass_sig) - return CDK_Out_Of_Core; - break; - - case CDK_PKT_LITERAL: - /* FIXME: We would need the size of the file name to allocate extra - bytes, otherwise the result would be useless. */ - pkt->pkt.literal = cdk_calloc(1, sizeof *pkt->pkt.literal); - if (!pkt->pkt.literal) - return CDK_Out_Of_Core; - pkt->pkt.literal->name = NULL; - break; - - default: - return CDK_Not_Implemented; - } - pkt->pkttype = pkttype; - *r_pkt = pkt; - return 0; -} - - -cdk_prefitem_t _cdk_copy_prefs(const cdk_prefitem_t prefs) -{ - size_t n = 0; - struct cdk_prefitem_s *new_prefs; - - if (!prefs) - return NULL; - - for (n = 0; prefs[n].type; n++); - new_prefs = cdk_calloc(1, sizeof *new_prefs * (n + 1)); - if (!new_prefs) - return NULL; - for (n = 0; prefs[n].type; n++) { - new_prefs[n].type = prefs[n].type; - new_prefs[n].value = prefs[n].value; - } - new_prefs[n].type = CDK_PREFTYPE_NONE; - new_prefs[n].value = 0; - return new_prefs; -} - - -cdk_error_t _cdk_copy_userid(cdk_pkt_userid_t * dst, cdk_pkt_userid_t src) -{ - cdk_pkt_userid_t u; - - if (!dst || !src) - return CDK_Inv_Value; - - *dst = NULL; - u = cdk_calloc(1, sizeof *u + strlen(src->name) + 2); - if (!u) - return CDK_Out_Of_Core; - u->name = (char *) u + sizeof(*u); - - memcpy(u, src, sizeof *u); - memcpy(u->name, src->name, strlen(src->name)); - u->prefs = _cdk_copy_prefs(src->prefs); - if (src->selfsig) - _cdk_copy_signature(&u->selfsig, src->selfsig); - *dst = u; - - return 0; -} - - -cdk_error_t _cdk_copy_pubkey(cdk_pkt_pubkey_t * dst, cdk_pkt_pubkey_t src) -{ - cdk_pkt_pubkey_t k; - int i; - - if (!dst || !src) - return CDK_Inv_Value; - - *dst = NULL; - k = cdk_calloc(1, sizeof *k); - if (!k) - return CDK_Out_Of_Core; - memcpy(k, src, sizeof *k); - if (src->uid) - _cdk_copy_userid(&k->uid, src->uid); - if (src->prefs) - k->prefs = _cdk_copy_prefs(src->prefs); - for (i = 0; i < cdk_pk_get_npkey(src->pubkey_algo); i++) - k->mpi[i] = _gnutls_mpi_copy(src->mpi[i]); - *dst = k; - - return 0; -} - - -cdk_error_t _cdk_copy_seckey(cdk_pkt_seckey_t * dst, cdk_pkt_seckey_t src) -{ - cdk_pkt_seckey_t k; - int i; - - if (!dst || !src) - return CDK_Inv_Value; - - *dst = NULL; - k = cdk_calloc(1, sizeof *k); - if (!k) - return CDK_Out_Of_Core; - memcpy(k, src, sizeof *k); - _cdk_copy_pubkey(&k->pk, src->pk); - - if (src->encdata) { - k->encdata = cdk_calloc(1, src->enclen + 1); - if (!k->encdata) - return CDK_Out_Of_Core; - memcpy(k->encdata, src->encdata, src->enclen); - } - - _cdk_s2k_copy(&k->protect.s2k, src->protect.s2k); - for (i = 0; i < cdk_pk_get_nskey(src->pubkey_algo); i++) { - k->mpi[i] = _gnutls_mpi_copy(src->mpi[i]); - } - - *dst = k; - return 0; -} - - -cdk_error_t _cdk_copy_pk_to_sk(cdk_pkt_pubkey_t pk, cdk_pkt_seckey_t sk) -{ - if (!pk || !sk) - return CDK_Inv_Value; - - sk->version = pk->version; - sk->expiredate = pk->expiredate; - sk->pubkey_algo = _pgp_pub_algo_to_cdk(pk->pubkey_algo); - sk->has_expired = pk->has_expired; - sk->is_revoked = pk->is_revoked; - sk->main_keyid[0] = pk->main_keyid[0]; - sk->main_keyid[1] = pk->main_keyid[1]; - sk->keyid[0] = pk->keyid[0]; - sk->keyid[1] = pk->keyid[1]; - - return 0; -} - - -cdk_error_t -_cdk_copy_signature(cdk_pkt_signature_t * dst, cdk_pkt_signature_t src) -{ - cdk_pkt_signature_t s; - - if (!dst || !src) - return CDK_Inv_Value; - - *dst = NULL; - s = cdk_calloc(1, sizeof *s); - if (!s) - return CDK_Out_Of_Core; - memcpy(s, src, sizeof *src); - _cdk_subpkt_copy(&s->hashed, src->hashed); - _cdk_subpkt_copy(&s->unhashed, src->unhashed); - /* FIXME: Copy MPI parts */ - *dst = s; - - return 0; -} - - -cdk_error_t _cdk_pubkey_compare(cdk_pkt_pubkey_t a, cdk_pkt_pubkey_t b) -{ - int na, nb, i; - - if (a->timestamp != b->timestamp - || a->pubkey_algo != b->pubkey_algo) - return -1; - if (a->version < 4 && a->expiredate != b->expiredate) - return -1; - na = cdk_pk_get_npkey(a->pubkey_algo); - nb = cdk_pk_get_npkey(b->pubkey_algo); - if (na != nb) - return -1; - - for (i = 0; i < na; i++) { - if (_gnutls_mpi_cmp(a->mpi[i], b->mpi[i])) - return -1; - } - - return 0; -} - - -/** - * cdk_subpkt_free: - * @ctx: the sub packet node to free - * - * Release the context. - **/ -void cdk_subpkt_free(cdk_subpkt_t ctx) -{ - cdk_subpkt_t s; - - while (ctx) { - s = ctx->next; - cdk_free(ctx); - ctx = s; - } -} - - -/** - * cdk_subpkt_find: - * @ctx: the sub packet node - * @type: the packet type to find - * - * Find the given packet type in the node. If no packet with this - * type was found, return null otherwise pointer to the node. - **/ -cdk_subpkt_t cdk_subpkt_find(cdk_subpkt_t ctx, size_t type) -{ - return cdk_subpkt_find_nth(ctx, type, 0); -} - -/** - * cdk_subpkt_type_count: - * @ctx: The sub packet context - * @type: The sub packet type. - * - * Return the amount of sub packets with this type. - **/ -size_t cdk_subpkt_type_count(cdk_subpkt_t ctx, size_t type) -{ - cdk_subpkt_t s; - size_t count; - - count = 0; - for (s = ctx; s; s = s->next) { - if (s->type == type) - count++; - } - - return count; -} - - -/** - * cdk_subpkt_find_nth: - * @ctx: The sub packet context - * @type: The sub packet type - * @index: The nth packet to retrieve, 0 means the first - * - * Return the nth sub packet of the given type. - **/ -cdk_subpkt_t cdk_subpkt_find_nth(cdk_subpkt_t ctx, size_t type, size_t idx) -{ - cdk_subpkt_t s; - size_t pos; - - pos = 0; - for (s = ctx; s; s = s->next) { - if (s->type == type && pos++ == idx) - return s; - } - - return NULL; -} - - -/** - * cdk_subpkt_new: - * @size: the size of the new context - * - * Create a new sub packet node with the size of @size. - **/ -cdk_subpkt_t cdk_subpkt_new(size_t size) -{ - cdk_subpkt_t s; - - if (!size) - return NULL; - s = cdk_calloc(1, sizeof *s + size + 2); - if (!s) - return NULL; - s->d = (byte *) s + sizeof(*s); - - return s; -} - - -/** - * cdk_subpkt_get_data: - * @ctx: the sub packet node - * @r_type: pointer store the packet type - * @r_nbytes: pointer to store the packet size - * - * Extract the data from the given sub packet. The type is returned - * in @r_type and the size in @r_nbytes. - **/ -const byte *cdk_subpkt_get_data(cdk_subpkt_t ctx, size_t * r_type, - size_t * r_nbytes) -{ - if (!ctx || !r_nbytes) - return NULL; - if (r_type) - *r_type = ctx->type; - *r_nbytes = ctx->size; - return ctx->d; -} - - -/** - * cdk_subpkt_add: - * @root: the root node - * @node: the node to add - * - * Add the node in @node to the root node @root. - **/ -cdk_error_t cdk_subpkt_add(cdk_subpkt_t root, cdk_subpkt_t node) -{ - cdk_subpkt_t n1; - - if (!root) - return CDK_Inv_Value; - for (n1 = root; n1->next; n1 = n1->next); - n1->next = node; - return 0; -} - - -byte *_cdk_subpkt_get_array(cdk_subpkt_t s, int count, size_t * r_nbytes) -{ - cdk_subpkt_t list; - byte *buf; - size_t n, nbytes; - - if (!s) { - if (r_nbytes) - *r_nbytes = 0; - return NULL; - } - - for (n = 0, list = s; list; list = list->next) { - n++; /* type */ - n += list->size; - if (list->size < 192) - n++; - else if (list->size < 8384) - n += 2; - else - n += 5; - } - buf = cdk_calloc(1, n + 1); - if (!buf) - return NULL; - - n = 0; - for (list = s; list; list = list->next) { - nbytes = 1 + list->size; /* type */ - if (nbytes < 192) - buf[n++] = nbytes; - else if (nbytes < 8384) { - nbytes -= 192; - buf[n++] = nbytes / 256 + 192; - buf[n++] = nbytes & 0xff; - } else { - buf[n++] = 0xFF; - buf[n++] = nbytes >> 24; - buf[n++] = nbytes >> 16; - buf[n++] = nbytes >> 8; - buf[n++] = nbytes; - } - - buf[n++] = list->type; - memcpy(buf + n, list->d, list->size); - n += list->size; - } - - if (count) { - cdk_free(buf); - buf = NULL; - } - if (r_nbytes) - *r_nbytes = n; - return buf; -} - - -cdk_error_t _cdk_subpkt_copy(cdk_subpkt_t * r_dst, cdk_subpkt_t src) -{ - cdk_subpkt_t root, p, node; - - if (!src || !r_dst) - return CDK_Inv_Value; - - root = NULL; - for (p = src; p; p = p->next) { - node = cdk_subpkt_new(p->size); - if (node) { - memcpy(node->d, p->d, p->size); - node->type = p->type; - node->size = p->size; - } - if (!root) - root = node; - else - cdk_subpkt_add(root, node); - } - *r_dst = root; - return 0; -} - - -/** - * cdk_subpkt_init: - * @node: the sub packet node - * @type: type of the packet which data should be initialized - * @buf: the buffer with the actual data - * @buflen: the size of the data - * - * Set the packet data of the given root and set the type of it. - **/ -void -cdk_subpkt_init(cdk_subpkt_t node, size_t type, - const void *buf, size_t buflen) -{ - if (!node) - return; - node->type = type; - node->size = buflen; - memcpy(node->d, buf, buflen); -} - - -/* FIXME: We need to think of a public interface for it. */ -const byte *cdk_key_desig_revoker_walk(cdk_desig_revoker_t root, - cdk_desig_revoker_t * ctx, - int *r_class, int *r_algid) -{ - cdk_desig_revoker_t n; - - if (!*ctx) { - *ctx = root; - n = root; - } else { - n = (*ctx)->next; - *ctx = n; - } - - if (n && r_class && r_algid) { - *r_class = n->r_class; - *r_algid = n->algid; - } - - return n ? n->fpr : NULL; -} - - -/** - * cdk_subpkt_find_next: - * @root: the base where to begin the iteration - * @type: the type to find or 0 for the next node. - * - * Try to find the next node after @root with type. - * If type is 0, the next node will be returned. - **/ -cdk_subpkt_t cdk_subpkt_find_next(cdk_subpkt_t root, size_t type) -{ - cdk_subpkt_t node; - - for (node = root->next; node; node = node->next) { - if (!type) - return node; - else if (node->type == type) - return node; - } - - return NULL; -} diff --git a/lib/opencdk/opencdk.h b/lib/opencdk/opencdk.h deleted file mode 100644 index 094a90ba47..0000000000 --- a/lib/opencdk/opencdk.h +++ /dev/null @@ -1,963 +0,0 @@ -/* opencdk.h - Open Crypto Development Kit (OpenCDK) - * Copyright (C) 2001-2012 Free Software Foundation, Inc. - * - * Author: Timo Schulz - * - * This file is part of OpenCDK. - * - * 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef OPENCDK_H -#define OPENCDK_H - -#include <config.h> -#include "gnutls_int.h" -#include <stddef.h> /* for size_t */ -#include <stdarg.h> -#include <mem.h> -#include <gnutls/gnutls.h> -#include "errors.h" -#include <hash_int.h> - -/* The OpenCDK version as a string. */ -#define OPENCDK_VERSION "0.6.6" - -/* The OpenCDK version as integer components major.minor.path */ -#define OPENCDK_VERSION_MAJOR 0 -#define OPENCDK_VERSION_MINOR 6 -#define OPENCDK_VERSION_PATCH 6 - -#ifdef __cplusplus -extern "C" { -#endif - -/* General contexts */ - -/* 'Session' handle to support the various options and run-time - information. */ - struct cdk_ctx_s; - typedef struct cdk_ctx_s *cdk_ctx_t; - -/* A generic context to store list of strings. */ - struct cdk_strlist_s; - typedef struct cdk_strlist_s *cdk_strlist_t; - -/* Context used to list keys of a keyring. */ - struct cdk_listkey_s; - typedef struct cdk_listkey_s *cdk_listkey_t; - -/* Opaque String to Key (S2K) handle. */ - struct cdk_s2k_s; - typedef struct cdk_s2k_s *cdk_s2k_t; - -/* Abstract I/O object, a stream, which is used for most operations. */ - struct cdk_stream_s; - typedef struct cdk_stream_s *cdk_stream_t; - -/* Opaque handle for the user ID preferences. */ - struct cdk_prefitem_s; - typedef struct cdk_prefitem_s *cdk_prefitem_t; - -/* Node to store a single key node packet. */ - struct cdk_kbnode_s; - typedef struct cdk_kbnode_s *cdk_kbnode_t; - -/* Key database handle. */ - struct cdk_keydb_hd_s; - typedef struct cdk_keydb_hd_s *cdk_keydb_hd_t; - - struct cdk_keydb_search_s; - typedef struct cdk_keydb_search_s *cdk_keydb_search_t; - -/* Context to store a list of recipient keys. */ - struct cdk_keylist_s; - typedef struct cdk_keylist_s *cdk_keylist_t; - -/* Context to encapsulate a single sub packet of a signature. */ - struct cdk_subpkt_s; - typedef struct cdk_subpkt_s *cdk_subpkt_t; - -/* Context used to generate key pairs. */ - struct cdk_keygen_ctx_s; - typedef struct cdk_keygen_ctx_s *cdk_keygen_ctx_t; - -/* Handle for a single designated revoker. */ - struct cdk_desig_revoker_s; - typedef struct cdk_desig_revoker_s *cdk_desig_revoker_t; - -/* Alias for backward compatibility. */ - typedef bigint_t cdk_mpi_t; - - -/* All valid error constants. */ - typedef enum { - CDK_EOF = -1, - CDK_Success = 0, - CDK_General_Error = 1, - CDK_File_Error = 2, - CDK_Bad_Sig = 3, - CDK_Inv_Packet = 4, - CDK_Inv_Algo = 5, - CDK_Not_Implemented = 6, - CDK_Armor_Error = 8, - CDK_Armor_CRC_Error = 9, - CDK_MPI_Error = 10, - CDK_Inv_Value = 11, - CDK_Error_No_Key = 12, - CDK_Chksum_Error = 13, - CDK_Time_Conflict = 14, - CDK_Zlib_Error = 15, - CDK_Weak_Key = 16, - CDK_Out_Of_Core = 17, - CDK_Wrong_Seckey = 18, - CDK_Bad_MDC = 19, - CDK_Inv_Mode = 20, - CDK_Error_No_Keyring = 21, - CDK_Wrong_Format = 22, - CDK_Inv_Packet_Ver = 23, - CDK_Too_Short = 24, - CDK_Unusable_Key = 25, - CDK_No_Data = 26, - CDK_No_Passphrase = 27, - CDK_Network_Error = 28 - } cdk_error_t; - - - enum cdk_control_flags { - CDK_CTLF_SET = 0, /* Value to set an option */ - CDK_CTLF_GET = 1, /* Value to get an option */ - CDK_CTL_DIGEST = 10, /* Option to set the digest algorithm. */ - CDK_CTL_ARMOR = 12, /* Option to enable armor output. */ - CDK_CTL_COMPRESS = 13, /* Option to enable compression. */ - CDK_CTL_COMPAT = 14, /* Option to switch in compat mode. */ - CDK_CTL_OVERWRITE = 15, /* Option to enable file overwritting. */ - CDK_CTL_S2K = 16, /* Option to set S2K values. */ - CDK_CTL_FORCE_DIGEST = 19, /* Force the use of a digest algorithm. */ - CDK_CTL_BLOCKMODE_ON = 20 /* Enable partial body lengths */ - }; - - -/* Specifies all valid log levels. */ - enum cdk_log_level_t { - CDK_LOG_NONE = 0, /* No log message will be shown. */ - CDK_LOG_INFO = 1, - CDK_LOG_DEBUG = 2, - CDK_LOG_DEBUG_PKT = 3 - }; - - -/* All valid compression algorithms in OpenPGP */ - enum cdk_compress_algo_t { - CDK_COMPRESS_NONE = 0, - CDK_COMPRESS_ZIP = 1, - CDK_COMPRESS_ZLIB = 2, - CDK_COMPRESS_BZIP2 = 3 /* Not supported in this version */ - }; - -/* All valid public key algorithms valid in OpenPGP */ - enum cdk_pubkey_algo_t { - CDK_PK_UNKNOWN = 0, - CDK_PK_RSA = 1, - CDK_PK_RSA_E = 2, /* RSA-E and RSA-S are deprecated use RSA instead */ - CDK_PK_RSA_S = 3, /* and use the key flags in the self signatures. */ - CDK_PK_ELG_E = 16, - CDK_PK_DSA = 17 - }; - -/* The valid 'String-To-Key' modes */ - enum cdk_s2k_type_t { - CDK_S2K_SIMPLE = 0, - CDK_S2K_SALTED = 1, - CDK_S2K_ITERSALTED = 3, - CDK_S2K_GNU_EXT = 101 - /* GNU extensions: refer to DETAILS from GnuPG: - http://cvs.gnupg.org/cgi-bin/viewcvs.cgi/trunk/doc/DETAILS?root=GnuPG - */ - }; - -/* The different kind of user ID preferences. */ - enum cdk_pref_type_t { - CDK_PREFTYPE_NONE = 0, - CDK_PREFTYPE_SYM = 1, /* Symmetric ciphers */ - CDK_PREFTYPE_HASH = 2, /* Message digests */ - CDK_PREFTYPE_ZIP = 3 /* Compression algorithms */ - }; - - -/* All valid sub packet types. */ - enum cdk_sig_subpacket_t { - CDK_SIGSUBPKT_NONE = 0, - CDK_SIGSUBPKT_SIG_CREATED = 2, - CDK_SIGSUBPKT_SIG_EXPIRE = 3, - CDK_SIGSUBPKT_EXPORTABLE = 4, - CDK_SIGSUBPKT_TRUST = 5, - CDK_SIGSUBPKT_REGEXP = 6, - CDK_SIGSUBPKT_REVOCABLE = 7, - CDK_SIGSUBPKT_KEY_EXPIRE = 9, - CDK_SIGSUBPKT_PREFS_SYM = 11, - CDK_SIGSUBPKT_REV_KEY = 12, - CDK_SIGSUBPKT_ISSUER = 16, - CDK_SIGSUBPKT_NOTATION = 20, - CDK_SIGSUBPKT_PREFS_HASH = 21, - CDK_SIGSUBPKT_PREFS_ZIP = 22, - CDK_SIGSUBPKT_KS_FLAGS = 23, - CDK_SIGSUBPKT_PREF_KS = 24, - CDK_SIGSUBPKT_PRIMARY_UID = 25, - CDK_SIGSUBPKT_POLICY = 26, - CDK_SIGSUBPKT_KEY_FLAGS = 27, - CDK_SIGSUBPKT_SIGNERS_UID = 28, - CDK_SIGSUBPKT_REVOC_REASON = 29, - CDK_SIGSUBPKT_FEATURES = 30 - }; - - -/* All valid armor types. */ - enum cdk_armor_type_t { - CDK_ARMOR_MESSAGE = 0, - CDK_ARMOR_PUBKEY = 1, - CDK_ARMOR_SECKEY = 2, - CDK_ARMOR_SIGNATURE = 3, - CDK_ARMOR_CLEARSIG = 4 - }; - - enum cdk_keydb_flag_t { - /* Valid database search modes */ - CDK_DBSEARCH_EXACT = 1, /* Exact string search */ - CDK_DBSEARCH_SUBSTR = 2, /* Sub string search */ - CDK_DBSEARCH_SHORT_KEYID = 3, /* 32-bit keyid search */ - CDK_DBSEARCH_KEYID = 4, /* 64-bit keyid search */ - CDK_DBSEARCH_FPR = 5, /* 160-bit fingerprint search */ - CDK_DBSEARCH_NEXT = 6, /* Enumerate all keys */ - CDK_DBSEARCH_AUTO = 7, /* Try to classify the string */ - /* Valid database types */ - CDK_DBTYPE_PK_KEYRING = 100, /* A file with one or more public keys */ - CDK_DBTYPE_SK_KEYRING = 101, /* A file with one or more secret keys */ - CDK_DBTYPE_DATA = 102, /* A buffer with at least one public key */ - }; - - -/* All valid modes for cdk_data_transform() */ - enum cdk_crypto_mode_t { - CDK_CRYPTYPE_NONE = 0, - CDK_CRYPTYPE_ENCRYPT = 1, - CDK_CRYPTYPE_DECRYPT = 2, - CDK_CRYPTYPE_SIGN = 3, - CDK_CRYPTYPE_VERIFY = 4, - CDK_CRYPTYPE_EXPORT = 5, - CDK_CRYPTYPE_IMPORT = 6 - }; - -#define CDK_KEY_USG_ENCR (CDK_KEY_USG_COMM_ENCR | CDK_KEY_USG_STORAGE_ENCR) -#define CDK_KEY_USG_SIGN (CDK_KEY_USG_DATA_SIGN | CDK_KEY_USG_CERT_SIGN) -/* A list of valid public key usages. */ - enum cdk_key_usage_t { - CDK_KEY_USG_CERT_SIGN = 1, - CDK_KEY_USG_DATA_SIGN = 2, - CDK_KEY_USG_COMM_ENCR = 4, - CDK_KEY_USG_STORAGE_ENCR = 8, - CDK_KEY_USG_SPLIT_KEY = 16, - CDK_KEY_USG_AUTH = 32, - CDK_KEY_USG_SHARED_KEY = 128 - }; - - -/* Valid flags for keys. */ - enum cdk_key_flag_t { - CDK_KEY_VALID = 0, - CDK_KEY_INVALID = 1, /* Missing or wrong self signature */ - CDK_KEY_EXPIRED = 2, /* Key is expired. */ - CDK_KEY_REVOKED = 4, /* Key has been revoked. */ - CDK_KEY_NOSIGNER = 8 - }; - - -/* Trust values and flags for keys and user IDs */ - enum cdk_trust_flag_t { - CDK_TRUST_UNKNOWN = 0, - CDK_TRUST_EXPIRED = 1, - CDK_TRUST_UNDEFINED = 2, - CDK_TRUST_NEVER = 3, - CDK_TRUST_MARGINAL = 4, - CDK_TRUST_FULLY = 5, - CDK_TRUST_ULTIMATE = 6, - /* trust flags */ - CDK_TFLAG_REVOKED = 32, - CDK_TFLAG_SUB_REVOKED = 64, - CDK_TFLAG_DISABLED = 128 - }; - - -/* Signature states and the signature modes. */ - enum cdk_signature_stat_t { - /* Signature status */ - CDK_SIGSTAT_NONE = 0, - CDK_SIGSTAT_GOOD = 1, - CDK_SIGSTAT_BAD = 2, - CDK_SIGSTAT_NOKEY = 3, - CDK_SIGSTAT_VALID = 4, /* True if made with a valid key. */ - /* FIXME: We need indicators for revoked/expires signatures. */ - - /* Signature modes */ - CDK_SIGMODE_NORMAL = 100, - CDK_SIGMODE_DETACHED = 101, - CDK_SIGMODE_CLEAR = 102 - }; - - -/* Key flags. */ - typedef enum { - CDK_FLAG_KEY_REVOKED = 256, - CDK_FLAG_KEY_EXPIRED = 512, - CDK_FLAG_SIG_EXPIRED = 1024 - } cdk_key_flags_t; - - -/* Possible format for the literal data. */ - typedef enum { - CDK_LITFMT_BINARY = 0, - CDK_LITFMT_TEXT = 1, - CDK_LITFMT_UNICODE = 2 - } cdk_lit_format_t; - -/* Valid OpenPGP packet types and their IDs */ - typedef enum { - CDK_PKT_RESERVED = 0, - CDK_PKT_PUBKEY_ENC = 1, - CDK_PKT_SIGNATURE = 2, - CDK_PKT_ONEPASS_SIG = 4, - CDK_PKT_SECRET_KEY = 5, - CDK_PKT_PUBLIC_KEY = 6, - CDK_PKT_SECRET_SUBKEY = 7, - CDK_PKT_COMPRESSED = 8, - CDK_PKT_MARKER = 10, - CDK_PKT_LITERAL = 11, - CDK_PKT_RING_TRUST = 12, - CDK_PKT_USER_ID = 13, - CDK_PKT_PUBLIC_SUBKEY = 14, - CDK_PKT_OLD_COMMENT = 16, - CDK_PKT_ATTRIBUTE = 17, - CDK_PKT_MDC = 19 - } cdk_packet_type_t; - -/* Define the maximal number of multiprecion integers for - a public key. */ -#define MAX_CDK_PK_PARTS 4 - -/* Define the maximal number of multiprecision integers for - a signature/encrypted blob issued by a secret key. */ -#define MAX_CDK_DATA_PARTS 2 - - -/* Helper macro to figure out if the packet is encrypted */ -#define CDK_PKT_IS_ENCRYPTED(pkttype) (\ - ((pkttype)==CDK_PKT_ENCRYPTED_MDC) \ - || ((pkttype)==CDK_PKT_ENCRYPTED)) - - - struct cdk_pkt_signature_s { - unsigned char version; - unsigned char sig_class; - unsigned int timestamp; - unsigned int expiredate; - unsigned int keyid[2]; - unsigned char pubkey_algo; - unsigned char digest_algo; - unsigned char digest_start[2]; - unsigned short hashed_size; - cdk_subpkt_t hashed; - unsigned short unhashed_size; - cdk_subpkt_t unhashed; - bigint_t mpi[MAX_CDK_DATA_PARTS]; - cdk_desig_revoker_t revkeys; - struct { - unsigned exportable:1; - unsigned revocable:1; - unsigned policy_url:1; - unsigned notation:1; - unsigned expired:1; - unsigned checked:1; - unsigned valid:1; - unsigned missing_key:1; - } flags; - unsigned int key[2]; /* only valid for key signatures */ - }; - typedef struct cdk_pkt_signature_s *cdk_pkt_signature_t; - - - struct cdk_pkt_userid_s { - unsigned int len; - unsigned is_primary:1; - unsigned is_revoked:1; - unsigned mdc_feature:1; - cdk_prefitem_t prefs; - size_t prefs_size; - unsigned char *attrib_img; /* Tag 17 if not null */ - size_t attrib_len; - cdk_pkt_signature_t selfsig; - char *name; - }; - typedef struct cdk_pkt_userid_s *cdk_pkt_userid_t; - - - struct cdk_pkt_pubkey_s { - unsigned char version; - unsigned char pubkey_algo; - unsigned char fpr[20]; - unsigned int keyid[2]; - unsigned int main_keyid[2]; - unsigned int timestamp; - unsigned int expiredate; - bigint_t mpi[MAX_CDK_PK_PARTS]; - unsigned is_revoked:1; - unsigned is_invalid:1; - unsigned has_expired:1; - int pubkey_usage; - cdk_pkt_userid_t uid; - cdk_prefitem_t prefs; - size_t prefs_size; - cdk_desig_revoker_t revkeys; - }; - typedef struct cdk_pkt_pubkey_s *cdk_pkt_pubkey_t; - -/* Alias to define a generic public key context. */ - typedef cdk_pkt_pubkey_t cdk_pubkey_t; - - - struct cdk_pkt_seckey_s { - cdk_pkt_pubkey_t pk; - unsigned int expiredate; - int version; - int pubkey_algo; - unsigned int keyid[2]; - unsigned int main_keyid[2]; - unsigned char s2k_usage; - struct { - unsigned char algo; - unsigned char sha1chk; /* SHA1 is used instead of a 16 bit checksum */ - cdk_s2k_t s2k; - unsigned char iv[16]; - unsigned char ivlen; - } protect; - unsigned short csum; - bigint_t mpi[MAX_CDK_PK_PARTS]; - unsigned char *encdata; - size_t enclen; - unsigned char is_protected; - unsigned is_primary:1; - unsigned has_expired:1; - unsigned is_revoked:1; - }; - typedef struct cdk_pkt_seckey_s *cdk_pkt_seckey_t; - -/* Alias to define a generic secret key context. */ - typedef cdk_pkt_seckey_t cdk_seckey_t; - - - struct cdk_pkt_onepass_sig_s { - unsigned char version; - unsigned int keyid[2]; - unsigned char sig_class; - unsigned char digest_algo; - unsigned char pubkey_algo; - unsigned char last; - }; - typedef struct cdk_pkt_onepass_sig_s *cdk_pkt_onepass_sig_t; - - - struct cdk_pkt_pubkey_enc_s { - unsigned char version; - unsigned int keyid[2]; - int throw_keyid; - unsigned char pubkey_algo; - bigint_t mpi[MAX_CDK_DATA_PARTS]; - }; - typedef struct cdk_pkt_pubkey_enc_s *cdk_pkt_pubkey_enc_t; - - struct cdk_pkt_encrypted_s { - unsigned int len; - int extralen; - unsigned char mdc_method; - cdk_stream_t buf; - }; - typedef struct cdk_pkt_encrypted_s *cdk_pkt_encrypted_t; - - - struct cdk_pkt_mdc_s { - unsigned char hash[20]; - }; - typedef struct cdk_pkt_mdc_s *cdk_pkt_mdc_t; - - - struct cdk_pkt_literal_s { - unsigned int len; - cdk_stream_t buf; - int mode; - unsigned int timestamp; - int namelen; - char *name; - }; - typedef struct cdk_pkt_literal_s *cdk_pkt_literal_t; - - - struct cdk_pkt_compressed_s { - unsigned int len; - int algorithm; - cdk_stream_t buf; - }; - typedef struct cdk_pkt_compressed_s *cdk_pkt_compressed_t; - - -/* Structure which represents a single OpenPGP packet. */ - struct cdk_packet_s { - size_t pktlen; /* real packet length */ - size_t pktsize; /* length with all headers */ - int old_ctb; /* 1 if RFC1991 mode is used */ - cdk_packet_type_t pkttype; - union { - cdk_pkt_mdc_t mdc; - cdk_pkt_userid_t user_id; - cdk_pkt_pubkey_t public_key; - cdk_pkt_seckey_t secret_key; - cdk_pkt_signature_t signature; - cdk_pkt_pubkey_enc_t pubkey_enc; - cdk_pkt_compressed_t compressed; - cdk_pkt_encrypted_t encrypted; - cdk_pkt_literal_t literal; - cdk_pkt_onepass_sig_t onepass_sig; - } pkt; - }; - typedef struct cdk_packet_s *cdk_packet_t; - -/* Allocate a new packet or a new packet with the given packet type. */ - cdk_error_t cdk_pkt_new(cdk_packet_t * r_pkt); - cdk_error_t cdk_pkt_alloc(cdk_packet_t * r_pkt, - cdk_packet_type_t pkttype); - -/* Only release the contents of the packet but not @PKT itself. */ - void cdk_pkt_free(cdk_packet_t pkt); - -/* Release the packet contents and the packet structure @PKT itself. */ - void cdk_pkt_release(cdk_packet_t pkt); - -/* Read or write the given output from or to the stream. */ - cdk_error_t cdk_pkt_read(cdk_stream_t inp, cdk_packet_t pkt, unsigned public); - cdk_error_t cdk_pkt_write(cdk_stream_t out, cdk_packet_t pkt); - -/* Sub packet routines */ - cdk_subpkt_t cdk_subpkt_new(size_t size); - void cdk_subpkt_free(cdk_subpkt_t ctx); - cdk_subpkt_t cdk_subpkt_find(cdk_subpkt_t ctx, size_t type); - cdk_subpkt_t cdk_subpkt_find_next(cdk_subpkt_t root, size_t type); - size_t cdk_subpkt_type_count(cdk_subpkt_t ctx, size_t type); - cdk_subpkt_t cdk_subpkt_find_nth(cdk_subpkt_t ctx, size_t type, - size_t index); - cdk_error_t cdk_subpkt_add(cdk_subpkt_t root, cdk_subpkt_t node); - const unsigned char *cdk_subpkt_get_data(cdk_subpkt_t ctx, - size_t * r_type, - size_t * r_nbytes); - void cdk_subpkt_init(cdk_subpkt_t node, size_t type, - const void *buf, size_t buflen); - -/* Designated Revoker routines */ - const unsigned char *cdk_key_desig_revoker_walk(cdk_desig_revoker_t - root, - cdk_desig_revoker_t - * ctx, - int *r_class, - int *r_algid); - -#define is_RSA(a) ((a) == CDK_PK_RSA \ - || (a) == CDK_PK_RSA_E \ - || (a) == CDK_PK_RSA_S) -#define is_ELG(a) ((a) == CDK_PK_ELG_E) -#define is_DSA(a) ((a) == CDK_PK_DSA) - -/* Encrypt the given session key @SK with the public key @PK - and write the contents into the packet @PKE. */ - cdk_error_t cdk_pk_encrypt(cdk_pubkey_t pk, - cdk_pkt_pubkey_enc_t pke, bigint_t sk); - -/* Decrypt the given encrypted session key in @PKE with the secret key - @SK and store it in @R_SK. */ - cdk_error_t cdk_pk_decrypt(cdk_seckey_t sk, - cdk_pkt_pubkey_enc_t pke, - bigint_t * r_sk); - -/* Sign the given message digest @MD with the secret key @SK and - store the signature in the packet @SIG. */ - cdk_error_t cdk_pk_sign(cdk_seckey_t sk, cdk_pkt_signature_t sig, - const unsigned char *md); - -/* Verify the given signature in @SIG with the public key @PK - and compare it against the message digest @MD. */ - cdk_error_t cdk_pk_verify(cdk_pubkey_t pk, cdk_pkt_signature_t sig, - const unsigned char *md); - -/* Use cdk_pk_get_npkey() and cdk_pk_get_nskey to find out how much - multiprecision integers a key consists of. */ - -/* Return a multi precision integer of the public key with the index @IDX - in the buffer @BUF. @R_NWRITTEN will contain the length in octets. - Optional @R_NBITS may contain the size in bits. */ - cdk_error_t cdk_pk_get_mpi(cdk_pubkey_t pk, size_t idx, - unsigned char *buf, size_t buflen, - size_t * r_nwritten, size_t * r_nbits); - -/* Same as the function above but of the secret key. */ - cdk_error_t cdk_sk_get_mpi(cdk_seckey_t sk, size_t idx, - unsigned char *buf, size_t buflen, - size_t * r_nwritten, size_t * r_nbits); - -/* Helper to get the exact number of multi precision integers - for the given object. */ - int cdk_pk_get_nbits(cdk_pubkey_t pk); - int cdk_pk_get_npkey(int algo); - int cdk_pk_get_nskey(int algo); - int cdk_pk_get_nsig(int algo); - int cdk_pk_get_nenc(int algo); - -/* Fingerprint and key ID routines. */ - -/* Calculate the fingerprint of the given public key. - the FPR parameter must be at least 20 octets to hold the SHA1 hash. */ - cdk_error_t cdk_pk_get_fingerprint(cdk_pubkey_t pk, - unsigned char *fpr); - -/* Same as above, but with additional sanity checks of the buffer size. */ - cdk_error_t cdk_pk_to_fingerprint(cdk_pubkey_t pk, - unsigned char *fpr, - size_t fprlen, size_t * r_nout); - -/* Derive the keyid from the fingerprint. This is only possible for - modern, version 4 keys. */ - unsigned int cdk_pk_fingerprint_get_keyid(const unsigned char *fpr, - size_t fprlen, - unsigned int *keyid); - -/* Various functions to get the keyid from the specific packet type. */ - unsigned int cdk_pk_get_keyid(cdk_pubkey_t pk, - unsigned int *keyid); - unsigned int cdk_sk_get_keyid(cdk_seckey_t sk, - unsigned int *keyid); - unsigned int cdk_sig_get_keyid(cdk_pkt_signature_t sig, - unsigned int *keyid); - -/* Key release functions. */ - void cdk_pk_release(cdk_pubkey_t pk); - void cdk_sk_release(cdk_seckey_t sk); - -/* Create a public key with the data from the secret key @SK. */ - cdk_error_t cdk_pk_from_secret_key(cdk_seckey_t sk, - cdk_pubkey_t * ret_pk); - -/* Sexp conversion of keys. */ - cdk_error_t cdk_pubkey_to_sexp(cdk_pubkey_t pk, char **sexp, - size_t * len); - cdk_error_t cdk_seckey_to_sexp(cdk_seckey_t sk, char **sexp, - size_t * len); - - -/* String to Key routines. */ - cdk_error_t cdk_s2k_new(cdk_s2k_t * ret_s2k, int mode, - int digest_algo, - const unsigned char *salt); - void cdk_s2k_free(cdk_s2k_t s2k); - -/* Protect the inbuf with ASCII armor of the specified type. - If @outbuf and @outlen are NULL, the function returns the calculated - size of the base64 encoded data in @nwritten. */ - cdk_error_t cdk_armor_encode_buffer(const unsigned char *inbuf, - size_t inlen, char *outbuf, - size_t outlen, - size_t * nwritten, int type); - - -/* This context contain user callbacks for different stream operations. - Some of these callbacks might be NULL to indicate that the callback - is not used. */ - struct cdk_stream_cbs_s { - cdk_error_t(*open) (void *); - cdk_error_t(*release) (void *); - int (*read) (void *, void *buf, size_t); - int (*write) (void *, const void *buf, size_t); - int (*seek) (void *, off_t); - }; - typedef struct cdk_stream_cbs_s *cdk_stream_cbs_t; - - int cdk_stream_is_compressed(cdk_stream_t s); - -/* Return a stream object which is associated to a socket. */ - cdk_error_t cdk_stream_sockopen(const char *host, - unsigned short port, - cdk_stream_t * ret_out); - -/* Return a stream object which is associated to an existing file. */ - cdk_error_t cdk_stream_open(const char *file, - cdk_stream_t * ret_s); - -/* Return a stream object which is associated to a file which will - be created when the stream is closed. */ - cdk_error_t cdk_stream_new(const char *file, cdk_stream_t * ret_s); - -/* Return a stream object with custom callback functions for the - various core operations. */ - cdk_error_t cdk_stream_new_from_cbs(cdk_stream_cbs_t cbs, - void *opa, - cdk_stream_t * ret_s); - cdk_error_t cdk_stream_create(const char *file, - cdk_stream_t * ret_s); - cdk_error_t cdk_stream_tmp_new(cdk_stream_t * r_out); - cdk_error_t cdk_stream_tmp_from_mem(const void *buf, size_t buflen, - cdk_stream_t * r_out); - void cdk_stream_tmp_set_mode(cdk_stream_t s, int val); - cdk_error_t cdk_stream_flush(cdk_stream_t s); - cdk_error_t cdk_stream_enable_cache(cdk_stream_t s, int val); - cdk_error_t cdk_stream_filter_disable(cdk_stream_t s, int type); - cdk_error_t cdk_stream_close(cdk_stream_t s); - off_t cdk_stream_get_length(cdk_stream_t s); - int cdk_stream_read(cdk_stream_t s, void *buf, size_t count); - int cdk_stream_write(cdk_stream_t s, const void *buf, - size_t count); - int cdk_stream_putc(cdk_stream_t s, int c); - int cdk_stream_getc(cdk_stream_t s); - int cdk_stream_eof(cdk_stream_t s); - off_t cdk_stream_tell(cdk_stream_t s); - cdk_error_t cdk_stream_seek(cdk_stream_t s, off_t offset); - cdk_error_t cdk_stream_set_armor_flag(cdk_stream_t s, int type); - -/* Push the literal filter for the given stream. */ - cdk_error_t cdk_stream_set_literal_flag(cdk_stream_t s, - cdk_lit_format_t mode, - const char *fname); - - cdk_error_t cdk_stream_set_compress_flag(cdk_stream_t s, int algo, - int level); - cdk_error_t cdk_stream_set_hash_flag(cdk_stream_t s, int algo); - cdk_error_t cdk_stream_set_text_flag(cdk_stream_t s, - const char *lf); - cdk_error_t cdk_stream_kick_off(cdk_stream_t inp, - cdk_stream_t out); - cdk_error_t cdk_stream_mmap(cdk_stream_t s, - unsigned char **ret_buf, - size_t * ret_buflen); - cdk_error_t cdk_stream_mmap_part(cdk_stream_t s, off_t off, - size_t len, - unsigned char **ret_buf, - size_t * ret_buflen); - -/* Read from the stream but restore the file pointer after reading - the requested amount of bytes. */ - int cdk_stream_peek(cdk_stream_t inp, unsigned char *buf, - size_t buflen); - -/* Create a new key db handle from a memory buffer. */ - cdk_error_t cdk_keydb_new_from_mem(cdk_keydb_hd_t * r_hd, - int secret, int armor, - const void *data, - size_t datlen); - -/* Check that a secret key with the given key ID is available. */ - cdk_error_t cdk_keydb_check_sk(cdk_keydb_hd_t hd, - unsigned int *keyid); - -/* Prepare the key db search. */ - cdk_error_t cdk_keydb_search_start(cdk_keydb_search_t * st, - cdk_keydb_hd_t db, int type, - void *desc); - - void cdk_keydb_search_release(cdk_keydb_search_t st); - -/* Return a key which matches a valid description given in - cdk_keydb_search_start(). */ - cdk_error_t cdk_keydb_search(cdk_keydb_search_t st, - cdk_keydb_hd_t hd, - cdk_kbnode_t * ret_key); - -/* Release the key db handle and all its resources. */ - void cdk_keydb_free(cdk_keydb_hd_t hd); - -/* The following functions will try to find a key in the given key - db handle either by keyid, by fingerprint or by some pattern. */ - cdk_error_t cdk_keydb_get_bykeyid(cdk_keydb_hd_t hd, - unsigned int *keyid, - cdk_kbnode_t * ret_pk); - cdk_error_t cdk_keydb_get_byfpr(cdk_keydb_hd_t hd, - const unsigned char *fpr, - cdk_kbnode_t * ret_pk); - cdk_error_t cdk_keydb_get_bypattern(cdk_keydb_hd_t hd, - const char *patt, - cdk_kbnode_t * ret_pk); - -/* These function, in contrast to most other key db functions, only - return the public or secret key packet without the additional - signatures and user IDs. */ - cdk_error_t cdk_keydb_get_pk(cdk_keydb_hd_t khd, - unsigned int *keyid, - cdk_pubkey_t * ret_pk); - cdk_error_t cdk_keydb_get_sk(cdk_keydb_hd_t khd, - unsigned int *keyid, - cdk_seckey_t * ret_sk); - -/* Try to read the next key block from the given input stream. - The key will be returned in @RET_KEY on success. */ - cdk_error_t cdk_keydb_get_keyblock(cdk_stream_t inp, - cdk_kbnode_t * ret_key, - unsigned public); - -/* Rebuild the key db index if possible. */ - cdk_error_t cdk_keydb_idx_rebuild(cdk_keydb_hd_t db, - cdk_keydb_search_t dbs); - -/* Export one or more keys from the given key db handle into - the stream @OUT. The export is done by substring search and - uses the string list @REMUSR for the pattern. */ - cdk_error_t cdk_keydb_export(cdk_keydb_hd_t hd, cdk_stream_t out, - cdk_strlist_t remusr); - -/* Import the given key node @knode into the key db. */ - cdk_error_t cdk_keydb_import(cdk_keydb_hd_t hd, - cdk_kbnode_t knode); - - -/* List or enumerate keys from a given key db handle. */ - -/* Start the key list process. Either use @PATT for a pattern search - or @FPATT for a list of pattern. */ - cdk_error_t cdk_listkey_start(cdk_listkey_t * r_ctx, - cdk_keydb_hd_t db, const char *patt, - cdk_strlist_t fpatt); - void cdk_listkey_close(cdk_listkey_t ctx); - -/* Return the next key which matches the pattern. */ - cdk_error_t cdk_listkey_next(cdk_listkey_t ctx, - cdk_kbnode_t * ret_key); - - cdk_kbnode_t cdk_kbnode_new(cdk_packet_t pkt); - cdk_error_t cdk_kbnode_read_from_mem(cdk_kbnode_t * ret_node, - int armor, - const unsigned char *buf, - size_t buflen, unsigned public); - cdk_error_t cdk_kbnode_write_to_mem(cdk_kbnode_t node, - unsigned char *buf, - size_t * r_nbytes); - cdk_error_t cdk_kbnode_write_to_mem_alloc(cdk_kbnode_t node, - unsigned char **r_buf, - size_t * r_buflen); - - void cdk_kbnode_release(cdk_kbnode_t node); - void cdk_kbnode_delete(cdk_kbnode_t node); - void cdk_kbnode_insert(cdk_kbnode_t root, cdk_kbnode_t node, - cdk_packet_type_t pkttype); - int cdk_kbnode_commit(cdk_kbnode_t * root); - void cdk_kbnode_remove(cdk_kbnode_t * root, cdk_kbnode_t node); - void cdk_kbnode_move(cdk_kbnode_t * root, cdk_kbnode_t node, - cdk_kbnode_t where); - cdk_kbnode_t cdk_kbnode_walk(cdk_kbnode_t root, cdk_kbnode_t * ctx, - int all); - cdk_packet_t cdk_kbnode_find_packet(cdk_kbnode_t node, - cdk_packet_type_t pkttype); - cdk_packet_t cdk_kbnode_get_packet(cdk_kbnode_t node); - cdk_kbnode_t cdk_kbnode_find(cdk_kbnode_t node, - cdk_packet_type_t pkttype); - cdk_kbnode_t cdk_kbnode_find_prev(cdk_kbnode_t root, - cdk_kbnode_t node, - cdk_packet_type_t pkttype); - cdk_kbnode_t cdk_kbnode_find_next(cdk_kbnode_t node, - cdk_packet_type_t pkttype); - cdk_error_t cdk_kbnode_hash(cdk_kbnode_t node, digest_hd_st * md, - int is_v4, cdk_packet_type_t pkttype, - int flags); - -/* Check each signature in the key node and return a summary of the - key status in @r_status. Values of cdk_key_flag_t are used. */ - cdk_error_t cdk_pk_check_sigs(cdk_kbnode_t knode, - cdk_keydb_hd_t hd, int *r_status); - -/* Check the self signature of the key to make sure it is valid. */ - cdk_error_t cdk_pk_check_self_sig(cdk_kbnode_t knode, - int *r_status); - -/* Return a matching algorithm from the given public key list. - @PREFTYPE can be either sym-cipher/compress/digest. */ - int cdk_pklist_select_algo(cdk_keylist_t pkl, int preftype); - -/* Return 0 or 1 if the given key list is able to understand the - MDC feature. */ - int cdk_pklist_use_mdc(cdk_keylist_t pkl); - cdk_error_t cdk_pklist_build(cdk_keylist_t * ret_pkl, - cdk_keydb_hd_t hd, - cdk_strlist_t remusr, int use); - void cdk_pklist_release(cdk_keylist_t pkl); - -/* Secret key lists */ - cdk_error_t cdk_sklist_build(cdk_keylist_t * ret_skl, - cdk_keydb_hd_t db, cdk_ctx_t hd, - cdk_strlist_t locusr, - int unlock, unsigned int use); - void cdk_sklist_release(cdk_keylist_t skl); - cdk_error_t cdk_sklist_write(cdk_keylist_t skl, cdk_stream_t outp, - digest_hd_st * mdctx, int sigclass, - int sigver); - cdk_error_t cdk_sklist_write_onepass(cdk_keylist_t skl, - cdk_stream_t outp, - int sigclass, int mdalgo); - -/* Encrypt the given stream @INP with the recipients given in @REMUSR. - If @REMUSR is NULL, symmetric encryption will be used. The output - will be written to @OUT. */ - cdk_error_t cdk_stream_encrypt(cdk_ctx_t hd, cdk_strlist_t remusr, - cdk_stream_t inp, cdk_stream_t out); - -/* Decrypt the @INP stream into @OUT. */ - cdk_error_t cdk_stream_decrypt(cdk_ctx_t hd, cdk_stream_t inp, - cdk_stream_t out); - -/* Same as the function above but it works on files. */ - cdk_error_t cdk_file_encrypt(cdk_ctx_t hd, cdk_strlist_t remusr, - const char *file, const char *output); - cdk_error_t cdk_file_decrypt(cdk_ctx_t hd, const char *file, - const char *output); - -/* Generic function to transform data. The mode can be either sign, - verify, encrypt, decrypt, import or export. The meanings of the - parameters are similar to the functions above. - @OUTBUF will contain the output and @OUTSIZE the length of it. */ - cdk_error_t cdk_data_transform(cdk_ctx_t hd, - enum cdk_crypto_mode_t mode, - cdk_strlist_t locusr, - cdk_strlist_t remusr, - const void *inbuf, size_t insize, - unsigned char **outbuf, - size_t * outsize, int modval); - - int cdk_trustdb_get_validity(cdk_stream_t inp, cdk_pkt_userid_t id, - int *r_val); - int cdk_trustdb_get_ownertrust(cdk_stream_t inp, cdk_pubkey_t pk, - int *r_val, int *r_flags); - - void cdk_strlist_free(cdk_strlist_t sl); - cdk_strlist_t cdk_strlist_add(cdk_strlist_t * list, - const char *string); - const char *cdk_check_version(const char *req_version); -/* UTF8 */ - char *cdk_utf8_encode(const char *string); - char *cdk_utf8_decode(const char *string, size_t length, - int delim); - -#ifdef __cplusplus -} -#endif -#endif /* OPENCDK_H */ diff --git a/lib/opencdk/packet.h b/lib/opencdk/packet.h deleted file mode 100644 index a5629ec44b..0000000000 --- a/lib/opencdk/packet.h +++ /dev/null @@ -1,46 +0,0 @@ -/* packet.h - * Copyright (C) 2002-2012 Free Software Foundation, Inc. - * - * Author: Timo Schulz - * - * This file is part of OpenCDK. - * - * 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef CDK_PACKET_H -#define CDK_PACKET_H - -struct cdk_kbnode_s { - struct cdk_kbnode_s *next; - cdk_packet_t pkt; - unsigned int is_deleted:1; - unsigned int is_cloned:1; -}; - -/*-- new-packet.c --*/ -void _cdk_free_mpibuf(size_t n, bigint_t * array); -void _cdk_free_userid(cdk_pkt_userid_t uid); -void _cdk_free_signature(cdk_pkt_signature_t sig); -cdk_prefitem_t _cdk_copy_prefs(const cdk_prefitem_t prefs); -cdk_error_t _cdk_copy_userid(cdk_pkt_userid_t * dst, cdk_pkt_userid_t src); -cdk_error_t _cdk_copy_pubkey(cdk_pkt_pubkey_t * dst, cdk_pkt_pubkey_t src); -cdk_error_t _cdk_copy_seckey(cdk_pkt_seckey_t * dst, cdk_pkt_seckey_t src); -cdk_error_t _cdk_copy_pk_to_sk(cdk_pkt_pubkey_t pk, cdk_pkt_seckey_t sk); -cdk_error_t _cdk_copy_signature(cdk_pkt_signature_t * dst, - cdk_pkt_signature_t src); -cdk_error_t _cdk_pubkey_compare(cdk_pkt_pubkey_t a, cdk_pkt_pubkey_t b); - -#endif /* CDK_PACKET_H */ diff --git a/lib/opencdk/pubkey.c b/lib/opencdk/pubkey.c deleted file mode 100644 index 6e3285e65e..0000000000 --- a/lib/opencdk/pubkey.c +++ /dev/null @@ -1,652 +0,0 @@ -/* pubkey.c - Public key API - * Copyright (C) 2002-2012 Free Software Foundation, Inc. - * - * Author: Timo Schulz - * - * This file is part of OpenCDK. - * - * The OpenCDK 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "gnutls_int.h" -#include <datum.h> -#include <pk.h> -#include <tls-sig.h> -#include <x509/common.h> -#include "opencdk.h" -#include "main.h" -#include "packet.h" - -/* This function gets the signature parameters and encodes - * them into a way for _gnutls_pk_verify to use. - */ -static cdk_error_t -sig_to_datum(gnutls_datum_t * r_sig, cdk_pkt_signature_t sig) -{ - int err; - cdk_error_t rc; - - if (!r_sig || !sig) - return CDK_Inv_Value; - - rc = 0; - if (is_RSA(sig->pubkey_algo)) { - err = _gnutls_mpi_dprint(sig->mpi[0], r_sig); - if (err < 0) - rc = map_gnutls_error(err); - } else if (is_DSA(sig->pubkey_algo)) { - err = - _gnutls_encode_ber_rs(r_sig, sig->mpi[0], sig->mpi[1]); - if (err < 0) - rc = map_gnutls_error(err); - } else - rc = CDK_Inv_Algo; - return rc; -} - -/** - * cdk_pk_verify: - * @pk: the public key - * @sig: signature - * @md: the message digest - * - * Verify the signature in @sig and compare it with the message digest in @md. - **/ -cdk_error_t -cdk_pk_verify(cdk_pubkey_t pk, cdk_pkt_signature_t sig, const byte * md) -{ - gnutls_datum_t s_sig = { NULL, 0 }, di = { - NULL, 0}; - byte *encmd = NULL; - cdk_error_t rc; - int ret, algo; - unsigned int i; - gnutls_pk_params_st params; - const mac_entry_st *me; - - if (!pk || !sig || !md) { - gnutls_assert(); - return CDK_Inv_Value; - } - - if (is_DSA(pk->pubkey_algo)) - algo = GNUTLS_PK_DSA; - else if (is_RSA(pk->pubkey_algo)) - algo = GNUTLS_PK_RSA; - else { - gnutls_assert(); - return CDK_Inv_Value; - } - - rc = sig_to_datum(&s_sig, sig); - if (rc) { - gnutls_assert(); - goto leave; - } - - me = mac_to_entry(sig->digest_algo); - rc = _gnutls_set_datum(&di, md, _gnutls_hash_get_algo_len(me)); - if (rc < 0) { - rc = gnutls_assert_val(CDK_Out_Of_Core); - goto leave; - } - - rc = pk_prepare_hash(algo, me, &di); - if (rc < 0) { - rc = gnutls_assert_val(CDK_General_Error); - goto leave; - } - - params.params_nr = cdk_pk_get_npkey(pk->pubkey_algo); - for (i = 0; i < params.params_nr; i++) - params.params[i] = pk->mpi[i]; - params.flags = 0; - ret = _gnutls_pk_verify(algo, &di, &s_sig, ¶ms, ¶ms.sign); - - if (ret < 0) { - gnutls_assert(); - rc = map_gnutls_error(ret); - goto leave; - } - - rc = 0; - - leave: - _gnutls_free_datum(&s_sig); - _gnutls_free_datum(&di); - cdk_free(encmd); - return rc; -} - - -/** - * cdk_pk_get_nbits: - * @pk: the public key - * - * Return the length of the public key in bits. - * The meaning of length is actually the size of the 'prime' - * object in the key. For RSA keys the modulus, for ElG/DSA - * the size of the public prime. - **/ -int cdk_pk_get_nbits(cdk_pubkey_t pk) -{ - if (!pk || !pk->mpi[0]) - return 0; - return _gnutls_mpi_get_nbits(pk->mpi[0]); -} - - -/** - * cdk_pk_get_npkey: - * @algo: The public key algorithm. - * - * Return the number of multiprecison integer forming an public - * key with the given algorithm. - */ -int cdk_pk_get_npkey(int algo) -{ - if (is_RSA(algo)) - return RSA_PUBLIC_PARAMS; - else if (is_DSA(algo)) - return DSA_PUBLIC_PARAMS; - else if (is_ELG(algo)) - return 3; - else { - gnutls_assert(); - return 0; - } -} - - -/** - * cdk_pk_get_nskey: - * @algo: the public key algorithm - * - * Return the number of multiprecision integers forming an - * secret key with the given algorithm. - **/ -int cdk_pk_get_nskey(int algo) -{ - int ret; - - if (is_RSA(algo)) - ret = RSA_PRIVATE_PARAMS - 2; /* we don't have exp1 and exp2 */ - else if (is_DSA(algo)) - ret = DSA_PRIVATE_PARAMS; - else if (is_ELG(algo)) - ret = 4; - else { - gnutls_assert(); - return 0; - } - - ret -= cdk_pk_get_npkey(algo); - return ret; -} - - -/** - * cdk_pk_get_nbits: - * @algo: the public key algorithm - * - * Return the number of MPIs a signature consists of. - **/ -int cdk_pk_get_nsig(int algo) -{ - if (is_RSA(algo)) - return 1; - else if (is_DSA(algo)) - return 2; - else - return 0; -} - - -/** - * cdk_pk_get_nenc: - * @algo: the public key algorithm - * - * Return the number of MPI's the encrypted data consists of. - **/ -int cdk_pk_get_nenc(int algo) -{ - if (is_RSA(algo)) - return 1; - else if (is_ELG(algo)) - return 2; - else - return 0; -} - - -int _cdk_pk_algo_usage(int algo) -{ - int usage; - - /* The ElGamal sign+encrypt algorithm is not supported any longer. */ - switch (algo) { - case CDK_PK_RSA: - usage = CDK_KEY_USG_SIGN | CDK_KEY_USG_ENCR; - break; - case CDK_PK_RSA_E: - usage = CDK_KEY_USG_ENCR; - break; - case CDK_PK_RSA_S: - usage = CDK_KEY_USG_SIGN; - break; - case CDK_PK_ELG_E: - usage = CDK_KEY_USG_ENCR; - break; - case CDK_PK_DSA: - usage = CDK_KEY_USG_SIGN; - break; - default: - usage = 0; - } - return usage; -} - -/* You can use a NULL buf to get the output size only - */ -static cdk_error_t -mpi_to_buffer(bigint_t a, byte * buf, size_t buflen, - size_t * r_nwritten, size_t * r_nbits) -{ - size_t nbits; - int err; - - if (!a || !r_nwritten) { - gnutls_assert(); - return CDK_Inv_Value; - } - - nbits = _gnutls_mpi_get_nbits(a); - if (r_nbits) - *r_nbits = nbits; - - if (r_nwritten) - *r_nwritten = (nbits + 7) / 8 + 2; - - if ((nbits + 7) / 8 + 2 > buflen) - return CDK_Too_Short; - - *r_nwritten = buflen; - err = _gnutls_mpi_print(a, buf, r_nwritten); - if (err < 0) { - gnutls_assert(); - return map_gnutls_error(err); - } - - return 0; -} - - -/** - * cdk_pk_get_mpi: - * @pk: public key - * @idx: index of the MPI to retrieve - * @buf: buffer to hold the raw data - * @r_nwritten: output how large the raw data is - * @r_nbits: size of the MPI in bits. - * - * Return the MPI with the given index of the public key. - **/ -cdk_error_t -cdk_pk_get_mpi(cdk_pubkey_t pk, size_t idx, - byte * buf, size_t buflen, size_t * r_nwritten, - size_t * r_nbits) -{ - if (!pk || !r_nwritten) - return CDK_Inv_Value; - - if ((ssize_t) idx > cdk_pk_get_npkey(pk->pubkey_algo)) - return CDK_Inv_Value; - return mpi_to_buffer(pk->mpi[idx], buf, buflen, r_nwritten, - r_nbits); -} - - -/** - * cdk_sk_get_mpi: - * @sk: secret key - * @idx: index of the MPI to retrieve - * @buf: buffer to hold the raw data - * @r_nwritten: output length of the raw data - * @r_nbits: length of the MPI data in bits. - * - * Return the MPI of the given secret key with the - * index @idx. It is important to check if the key - * is protected and thus no real MPI data will be returned then. - **/ -cdk_error_t -cdk_sk_get_mpi(cdk_pkt_seckey_t sk, size_t idx, - byte * buf, size_t buflen, size_t * r_nwritten, - size_t * r_nbits) -{ - if (!sk || !r_nwritten) - return CDK_Inv_Value; - - if ((ssize_t) idx > cdk_pk_get_nskey(sk->pubkey_algo)) - return CDK_Inv_Value; - return mpi_to_buffer(sk->mpi[idx], buf, buflen, r_nwritten, - r_nbits); -} - - -static u16 checksum_mpi(bigint_t m) -{ - byte buf[MAX_MPI_BYTES + 2]; - size_t nread; - unsigned int i; - u16 chksum = 0; - - if (!m) - return 0; - nread = DIM(buf); - if (_gnutls_mpi_print_pgp(m, buf, &nread) < 0) - return 0; - for (i = 0; i < nread; i++) - chksum += buf[i]; - return chksum; -} - -/** - * cdk_pk_from_secret_key: - * @sk: the secret key - * @ret_pk: the new public key - * - * Create a new public key from a secret key. - **/ -cdk_error_t -cdk_pk_from_secret_key(cdk_pkt_seckey_t sk, cdk_pubkey_t * ret_pk) -{ - if (!sk) - return CDK_Inv_Value; - return _cdk_copy_pubkey(ret_pk, sk->pk); -} - - -int _cdk_sk_get_csum(cdk_pkt_seckey_t sk) -{ - u16 csum = 0, i; - - if (!sk) - return 0; - for (i = 0; i < cdk_pk_get_nskey(sk->pubkey_algo); i++) - csum += checksum_mpi(sk->mpi[i]); - return csum; -} - - -/** - * cdk_pk_get_fingerprint: - * @pk: the public key - * @fpr: the buffer to hold the fingerprint - * - * Return the fingerprint of the given public key. - * The buffer must be at least 20 octets. - * This function should be considered deprecated and - * the new cdk_pk_to_fingerprint() should be used whenever - * possible to avoid overflows. - **/ -cdk_error_t cdk_pk_get_fingerprint(cdk_pubkey_t pk, byte * fpr) -{ - digest_hd_st hd; - int md_algo; - int dlen = 0; - int err; - const mac_entry_st *me; - - if (!pk || !fpr) - return CDK_Inv_Value; - - if (pk->version < 4 && is_RSA(pk->pubkey_algo)) - md_algo = GNUTLS_DIG_MD5; /* special */ - else - md_algo = GNUTLS_DIG_SHA1; - - me = mac_to_entry(md_algo); - - dlen = _gnutls_hash_get_algo_len(me); - err = _gnutls_hash_init(&hd, me); - if (err < 0) { - gnutls_assert(); - return map_gnutls_error(err); - } - _cdk_hash_pubkey(pk, &hd, 1); - _gnutls_hash_deinit(&hd, fpr); - if (dlen == 16) - memset(fpr + 16, 0, 4); - return 0; -} - - -/** - * cdk_pk_to_fingerprint: - * @pk: the public key - * @fprbuf: buffer to save the fingerprint - * @fprbuflen: buffer size - * @r_nout: actual length of the fingerprint. - * - * Calculate a fingerprint of the given key and - * return it in the given byte array. - **/ -cdk_error_t -cdk_pk_to_fingerprint(cdk_pubkey_t pk, - byte * fprbuf, size_t fprbuflen, size_t * r_nout) -{ - size_t key_fprlen; - cdk_error_t err; - - if (!pk) - return CDK_Inv_Value; - - if (pk->version < 4) - key_fprlen = 16; - else - key_fprlen = 20; - - /* Only return the required buffer size for the fingerprint. */ - if (!fprbuf && !fprbuflen && r_nout) { - *r_nout = key_fprlen; - return 0; - } - - if (!fprbuf || key_fprlen > fprbuflen) - return CDK_Too_Short; - - err = cdk_pk_get_fingerprint(pk, fprbuf); - if (r_nout) - *r_nout = key_fprlen; - - return err; -} - - -/** - * cdk_pk_fingerprint_get_keyid: - * @fpr: the key fingerprint - * @fprlen: the length of the fingerprint - * - * Derive the key ID from the key fingerprint. - * For version 3 keys, this is not working. - **/ -u32 -cdk_pk_fingerprint_get_keyid(const byte * fpr, size_t fprlen, u32 * keyid) -{ - u32 lowbits = 0; - - /* In this case we say the key is a V3 RSA key and we can't - use the fingerprint to get the keyid. */ - if (fpr && fprlen == 16) { - keyid[0] = 0; - keyid[1] = 0; - return 0; - } else if (keyid && fpr) { - keyid[0] = _cdk_buftou32(fpr + 12); - keyid[1] = _cdk_buftou32(fpr + 16); - lowbits = keyid[1]; - } else if (fpr) - lowbits = _cdk_buftou32(fpr + 16); - return lowbits; -} - - -/** - * cdk_pk_get_keyid: - * @pk: the public key - * @keyid: buffer to store the key ID - * - * Calculate the key ID of the given public key. - **/ -u32 cdk_pk_get_keyid(cdk_pubkey_t pk, u32 * keyid) -{ - u32 lowbits = 0; - byte buf[24]; - int rc; - - if (pk && (!pk->keyid[0] || !pk->keyid[1])) { - if (pk->version < 4 && is_RSA(pk->pubkey_algo)) { - byte p[MAX_MPI_BYTES]; - size_t n; - - n = MAX_MPI_BYTES; - rc = _gnutls_mpi_print(pk->mpi[0], p, &n); - if (rc < 0 || n < 8) { - keyid[0] = keyid[1] = (u32)-1; - return (u32)-1; - } - - pk->keyid[0] = - p[n - 8] << 24 | p[n - 7] << 16 | p[n - - 6] << 8 | - p[n - 5]; - pk->keyid[1] = - p[n - 4] << 24 | p[n - 3] << 16 | p[n - - 2] << 8 | - p[n - 1]; - } else if (pk->version == 4) { - cdk_pk_get_fingerprint(pk, buf); - pk->keyid[0] = _cdk_buftou32(buf + 12); - pk->keyid[1] = _cdk_buftou32(buf + 16); - } - } - lowbits = pk ? pk->keyid[1] : 0; - if (keyid && pk) { - keyid[0] = pk->keyid[0]; - keyid[1] = pk->keyid[1]; - } - - return lowbits; -} - - -/** - * cdk_sk_get_keyid: - * @sk: the secret key - * @keyid: buffer to hold the key ID - * - * Calculate the key ID of the secret key, actually the public key. - **/ -u32 cdk_sk_get_keyid(cdk_pkt_seckey_t sk, u32 * keyid) -{ - u32 lowbits = 0; - - if (sk && sk->pk) { - lowbits = cdk_pk_get_keyid(sk->pk, keyid); - sk->keyid[0] = sk->pk->keyid[0]; - sk->keyid[1] = sk->pk->keyid[1]; - } - - return lowbits; -} - - -/** - * cdk_sig_get_keyid: - * @sig: the signature - * @keyid: buffer to hold the key ID - * - * Retrieve the key ID from the given signature. - **/ -u32 cdk_sig_get_keyid(cdk_pkt_signature_t sig, u32 * keyid) -{ - u32 lowbits = sig ? sig->keyid[1] : 0; - - if (keyid && sig) { - keyid[0] = sig->keyid[0]; - keyid[1] = sig->keyid[1]; - } - return lowbits; -} - - -/* Return the key ID from the given packet. - If this is not possible, 0 is returned */ -u32 _cdk_pkt_get_keyid(cdk_packet_t pkt, u32 * keyid) -{ - u32 lowbits; - - if (!pkt) - return 0; - - switch (pkt->pkttype) { - case CDK_PKT_PUBLIC_KEY: - case CDK_PKT_PUBLIC_SUBKEY: - lowbits = cdk_pk_get_keyid(pkt->pkt.public_key, keyid); - break; - - case CDK_PKT_SECRET_KEY: - case CDK_PKT_SECRET_SUBKEY: - lowbits = cdk_sk_get_keyid(pkt->pkt.secret_key, keyid); - break; - - case CDK_PKT_SIGNATURE: - lowbits = cdk_sig_get_keyid(pkt->pkt.signature, keyid); - break; - - default: - lowbits = 0; - break; - } - - return lowbits; -} - - -/* Get the fingerprint of the packet if possible. */ -cdk_error_t _cdk_pkt_get_fingerprint(cdk_packet_t pkt, byte * fpr) -{ - if (!pkt || !fpr) - return CDK_Inv_Value; - - switch (pkt->pkttype) { - case CDK_PKT_PUBLIC_KEY: - case CDK_PKT_PUBLIC_SUBKEY: - return cdk_pk_get_fingerprint(pkt->pkt.public_key, fpr); - - case CDK_PKT_SECRET_KEY: - case CDK_PKT_SECRET_SUBKEY: - return cdk_pk_get_fingerprint(pkt->pkt.secret_key->pk, - fpr); - - default: - return CDK_Inv_Mode; - } - return 0; -} diff --git a/lib/opencdk/read-packet.c b/lib/opencdk/read-packet.c deleted file mode 100644 index f86659a023..0000000000 --- a/lib/opencdk/read-packet.c +++ /dev/null @@ -1,1180 +0,0 @@ -/* read-packet.c - Read OpenPGP packets - * Copyright (C) 2001-2012 Free Software Foundation, Inc. - * - * Author: Timo Schulz - * - * This file is part of OpenCDK. - * - * The OpenCDK 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <string.h> -#include <stdio.h> -#include <time.h> -#include <assert.h> - -#include "opencdk.h" -#include "main.h" -#include "packet.h" -#include "types.h" -#include <algorithms.h> -#include <str.h> -#include <minmax.h> - -/* The version of the MDC packet considering the lastest OpenPGP draft. */ - -static int -stream_read(cdk_stream_t s, void *buf, size_t buflen, size_t * r_nread) -{ - int res = cdk_stream_read(s, buf, buflen); - - if (res > 0) { - *r_nread = res; - return 0; - } else { - return (cdk_stream_eof(s) ? EOF : _cdk_stream_get_errno(s)); - } -} - - -/* Try to read 4 octets from the stream. */ -static u32 read_32(cdk_stream_t s) -{ - byte buf[4]; - size_t nread = 0; - - assert(s != NULL); - - stream_read(s, buf, 4, &nread); - if (nread != 4) - return (u32) -1; - return buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]; -} - - -/* Try to read 2 octets from a stream. */ -static u16 read_16(cdk_stream_t s) -{ - byte buf[2]; - size_t nread = 0; - - assert(s != NULL); - - stream_read(s, buf, 2, &nread); - if (nread != 2) - return (u16) - 1; - return buf[0] << 8 | buf[1]; -} - - -/* read about S2K at http://tools.ietf.org/html/rfc4880#section-3.7.1 */ -static cdk_error_t read_s2k(cdk_stream_t inp, cdk_s2k_t s2k) -{ - size_t nread = 0; - - s2k->mode = cdk_stream_getc(inp); - s2k->hash_algo = cdk_stream_getc(inp); - if (s2k->mode == CDK_S2K_SIMPLE) - return 0; - else if (s2k->mode == CDK_S2K_SALTED - || s2k->mode == CDK_S2K_ITERSALTED) { - if (stream_read(inp, s2k->salt, DIM(s2k->salt), &nread)) - return CDK_Inv_Packet; - if (nread != DIM(s2k->salt)) - return CDK_Inv_Packet; - - if (s2k->mode == CDK_S2K_ITERSALTED) - s2k->count = cdk_stream_getc(inp); - } else if (s2k->mode == CDK_S2K_GNU_EXT) { - /* GNU extensions to the S2K : read DETAILS from gnupg */ - return 0; - } else - return CDK_Not_Implemented; - - return 0; -} - - -static cdk_error_t read_mpi(cdk_stream_t inp, bigint_t * ret_m, int secure) -{ - bigint_t m; - int err; - byte buf[MAX_MPI_BYTES + 2]; - size_t nread, nbits; - cdk_error_t rc; - - if (!inp || !ret_m) - return CDK_Inv_Value; - - *ret_m = NULL; - nbits = read_16(inp); - nread = (nbits + 7) / 8; - - if (nbits > MAX_MPI_BITS || nbits == 0) { - _gnutls_write_log("read_mpi: too large %d bits\n", - (int) nbits); - return gnutls_assert_val(CDK_MPI_Error); /* Sanity check */ - } - - rc = stream_read(inp, buf + 2, nread, &nread); - if (!rc && nread != ((nbits + 7) / 8)) { - _gnutls_write_log("read_mpi: too short %d < %d\n", - (int) nread, (int) ((nbits + 7) / 8)); - return gnutls_assert_val(CDK_MPI_Error); - } - - buf[0] = nbits >> 8; - buf[1] = nbits >> 0; - nread += 2; - err = _gnutls_mpi_init_scan_pgp(&m, buf, nread); - if (err < 0) - return gnutls_assert_val(map_gnutls_error(err)); - - *ret_m = m; - return rc; -} - - -/* Read the encoded packet length directly from the file - object INP and return it. Reset RET_PARTIAL if this is - the last packet in block mode. */ -size_t _cdk_pkt_read_len(FILE * inp, size_t * ret_partial) -{ - int c1, c2; - size_t pktlen; - - c1 = fgetc(inp); - if (c1 == EOF) - return (size_t) EOF; - if (c1 < 224 || c1 == 255) - *ret_partial = 0; /* End of partial data */ - if (c1 < 192) - pktlen = c1; - else if (c1 >= 192 && c1 <= 223) { - c2 = fgetc(inp); - if (c2 == EOF) - return (size_t) EOF; - pktlen = ((c1 - 192) << 8) + c2 + 192; - } else if (c1 == 255) { - pktlen = fgetc(inp) << 24; - pktlen |= fgetc(inp) << 16; - pktlen |= fgetc(inp) << 8; - pktlen |= fgetc(inp) << 0; - } else - pktlen = 1 << (c1 & 0x1f); - return pktlen; -} - - -static cdk_error_t -read_pubkey_enc(cdk_stream_t inp, size_t pktlen, cdk_pkt_pubkey_enc_t pke) -{ - size_t i, nenc; - - if (!inp || !pke) - return CDK_Inv_Value; - - if (DEBUG_PKT) - _gnutls_write_log("read_pubkey_enc: %d octets\n", - (int) pktlen); - - if (pktlen < 12) - return CDK_Inv_Packet; - pke->version = cdk_stream_getc(inp); - if (pke->version < 2 || pke->version > 3) - return CDK_Inv_Packet; - pke->keyid[0] = read_32(inp); - pke->keyid[1] = read_32(inp); - if (!pke->keyid[0] && !pke->keyid[1]) - pke->throw_keyid = 1; /* RFC2440 "speculative" keyID */ - pke->pubkey_algo = _pgp_pub_algo_to_cdk(cdk_stream_getc(inp)); - nenc = cdk_pk_get_nenc(pke->pubkey_algo); - if (!nenc) - return CDK_Inv_Algo; - for (i = 0; i < nenc; i++) { - cdk_error_t rc = read_mpi(inp, &pke->mpi[i], 0); - if (rc) - return gnutls_assert_val(rc); - } - - return 0; -} - - - -static cdk_error_t read_mdc(cdk_stream_t inp, cdk_pkt_mdc_t mdc) -{ - size_t n = 0; - cdk_error_t rc; - - if (!inp || !mdc) - return CDK_Inv_Value; - - if (DEBUG_PKT) - _gnutls_write_log("read_mdc:\n"); - - rc = stream_read(inp, mdc->hash, DIM(mdc->hash), &n); - if (rc) - return rc; - - return n != DIM(mdc->hash) ? CDK_Inv_Packet : 0; -} - - -static cdk_error_t -read_compressed(cdk_stream_t inp, size_t pktlen, cdk_pkt_compressed_t c) -{ - if (!inp || !c) - return CDK_Inv_Value; - - if (DEBUG_PKT) - _gnutls_write_log("read_compressed: %d octets\n", - (int) pktlen); - - c->algorithm = cdk_stream_getc(inp); - if (c->algorithm > 3) - return CDK_Inv_Packet; - - /* don't know the size, so we read until EOF */ - if (!pktlen) { - c->len = 0; - c->buf = inp; - } - - /* FIXME: Support partial bodies. */ - return 0; -} - - -static cdk_error_t -read_public_key(cdk_stream_t inp, size_t pktlen, cdk_pkt_pubkey_t pk) -{ - size_t i, ndays, npkey; - - if (!inp || !pk) - return CDK_Inv_Value; - - if (DEBUG_PKT) - _gnutls_write_log("read_public_key: %d octets\n", - (int) pktlen); - - pk->is_invalid = 1; /* default to detect missing self signatures */ - pk->is_revoked = 0; - pk->has_expired = 0; - - pk->version = cdk_stream_getc(inp); - if (pk->version < 2 || pk->version > 4) - return CDK_Inv_Packet_Ver; - pk->timestamp = read_32(inp); - if (pk->version < 4) { - ndays = read_16(inp); - if (ndays) - pk->expiredate = pk->timestamp + ndays * 86400L; - } - - pk->pubkey_algo = _pgp_pub_algo_to_cdk(cdk_stream_getc(inp)); - npkey = cdk_pk_get_npkey(pk->pubkey_algo); - if (!npkey) { - gnutls_assert(); - _gnutls_write_log("invalid public key algorithm %d\n", - pk->pubkey_algo); - return CDK_Inv_Algo; - } - for (i = 0; i < npkey; i++) { - cdk_error_t rc = read_mpi(inp, &pk->mpi[i], 0); - if (rc) - return gnutls_assert_val(rc); - } - - /* This value is just for the first run and will be - replaced with the actual key flags from the self signature. */ - pk->pubkey_usage = 0; - return 0; -} - - -static cdk_error_t -read_public_subkey(cdk_stream_t inp, size_t pktlen, cdk_pkt_pubkey_t pk) -{ - if (!inp || !pk) - return CDK_Inv_Value; - return read_public_key(inp, pktlen, pk); -} - -static cdk_error_t -read_secret_key(cdk_stream_t inp, size_t pktlen, cdk_pkt_seckey_t sk) -{ - size_t p1, p2, nread = 0; - int i, nskey; - int rc; - - if (!inp || !sk || !sk->pk) - return CDK_Inv_Value; - - if (DEBUG_PKT) - _gnutls_write_log("read_secret_key: %d octets\n", - (int) pktlen); - - p1 = cdk_stream_tell(inp); - rc = read_public_key(inp, pktlen, sk->pk); - if (rc) - return rc; - - sk->s2k_usage = cdk_stream_getc(inp); - sk->protect.sha1chk = 0; - if (sk->s2k_usage == 254 || sk->s2k_usage == 255) { - sk->protect.sha1chk = (sk->s2k_usage == 254); - sk->protect.algo = - _pgp_cipher_to_gnutls(cdk_stream_getc(inp)); - if (sk->protect.algo == GNUTLS_CIPHER_UNKNOWN) - return gnutls_assert_val(CDK_Inv_Algo); - - sk->protect.s2k = cdk_calloc(1, sizeof *sk->protect.s2k); - if (!sk->protect.s2k) - return CDK_Out_Of_Core; - rc = read_s2k(inp, sk->protect.s2k); - if (rc) - return rc; - /* refer to --export-secret-subkeys in gpg(1) */ - if (sk->protect.s2k->mode == CDK_S2K_GNU_EXT) - sk->protect.ivlen = 0; - else { - sk->protect.ivlen = - gnutls_cipher_get_block_size(sk->protect.algo); - if (!sk->protect.ivlen) - return CDK_Inv_Packet; - rc = stream_read(inp, sk->protect.iv, - sk->protect.ivlen, &nread); - if (rc) - return rc; - if (nread != sk->protect.ivlen) - return CDK_Inv_Packet; - } - } else - sk->protect.algo = _pgp_cipher_to_gnutls(sk->s2k_usage); - if (sk->protect.algo == GNUTLS_CIPHER_UNKNOWN) - return gnutls_assert_val(CDK_Inv_Algo); - else if (sk->protect.algo == GNUTLS_CIPHER_NULL) { - sk->csum = 0; - nskey = cdk_pk_get_nskey(sk->pk->pubkey_algo); - if (!nskey) { - gnutls_assert(); - return CDK_Inv_Algo; - } - for (i = 0; i < nskey; i++) { - rc = read_mpi(inp, &sk->mpi[i], 1); - if (rc) - return gnutls_assert_val(rc); - } - sk->csum = read_16(inp); - sk->is_protected = 0; - } else if (sk->pk->version < 4) { - /* The length of each multiprecision integer is stored in plaintext. */ - nskey = cdk_pk_get_nskey(sk->pk->pubkey_algo); - if (!nskey) { - gnutls_assert(); - return CDK_Inv_Algo; - } - for (i = 0; i < nskey; i++) { - rc = read_mpi(inp, &sk->mpi[i], 1); - if (rc) - return gnutls_assert_val(rc); - } - sk->csum = read_16(inp); - sk->is_protected = 1; - } else { - /* We need to read the rest of the packet because we do not - have any information how long the encrypted mpi's are */ - p2 = cdk_stream_tell(inp); - p2 -= p1; - sk->enclen = pktlen - p2; - if (sk->enclen < 2) - return CDK_Inv_Packet; /* at least 16 bits for the checksum! */ - sk->encdata = cdk_calloc(1, sk->enclen + 1); - if (!sk->encdata) - return CDK_Out_Of_Core; - if (stream_read(inp, sk->encdata, sk->enclen, &nread)) - return CDK_Inv_Packet; - /* Handle the GNU S2K extensions we know (just gnu-dummy right now): */ - if (sk->protect.s2k->mode == CDK_S2K_GNU_EXT) { - unsigned char gnumode; - if ((sk->enclen < strlen("GNU") + 1) || - (0 != - memcmp("GNU", sk->encdata, strlen("GNU")))) - return CDK_Inv_Packet; - gnumode = sk->encdata[strlen("GNU")]; - /* we only handle gnu-dummy (mode 1). - mode 2 should refer to external smart cards. - */ - if (gnumode != 1) - return CDK_Inv_Packet; - /* gnu-dummy should have no more data */ - if (sk->enclen != strlen("GNU") + 1) - return CDK_Inv_Packet; - } - nskey = cdk_pk_get_nskey(sk->pk->pubkey_algo); - if (!nskey) { - gnutls_assert(); - return CDK_Inv_Algo; - } - /* We mark each MPI entry with NULL to indicate a protected key. */ - for (i = 0; i < nskey; i++) - sk->mpi[i] = NULL; - sk->is_protected = 1; - } - - sk->is_primary = 1; - _cdk_copy_pk_to_sk(sk->pk, sk); - return 0; -} - - -static cdk_error_t -read_secret_subkey(cdk_stream_t inp, size_t pktlen, cdk_pkt_seckey_t sk) -{ - cdk_error_t rc; - - if (!inp || !sk || !sk->pk) - return CDK_Inv_Value; - - rc = read_secret_key(inp, pktlen, sk); - sk->is_primary = 0; - return rc; -} - -#define ATTRIBUTE "[attribute]" - -static cdk_error_t -read_attribute(cdk_stream_t inp, size_t pktlen, cdk_pkt_userid_t attr, - int name_size) -{ - const byte *p; - byte *buf; - size_t len, nread; - cdk_error_t rc; - - if (!inp || !attr || !pktlen) - return CDK_Inv_Value; - - if (DEBUG_PKT) - _gnutls_write_log("read_attribute: %d octets\n", - (int) pktlen); - - _gnutls_str_cpy(attr->name, name_size, ATTRIBUTE); - attr->len = MIN(name_size, sizeof(ATTRIBUTE) - 1); - - buf = cdk_calloc(1, pktlen); - if (!buf) - return CDK_Out_Of_Core; - rc = stream_read(inp, buf, pktlen, &nread); - if (rc) { - gnutls_assert(); - rc = CDK_Inv_Packet; - goto error; - } - - p = buf; - len = *p++; - pktlen--; - - if (len == 255) { - if (pktlen < 4) { - gnutls_assert(); - rc = CDK_Inv_Packet; - goto error; - } - - len = _cdk_buftou32(p); - p += 4; - pktlen -= 4; - } else if (len >= 192) { - if (pktlen < 2) { - gnutls_assert(); - rc = CDK_Inv_Packet; - goto error; - } - - len = ((len - 192) << 8) + *p + 192; - p++; - pktlen--; - } - - if (!len || pktlen == 0 || *p != 1) { /* Currently only 1, meaning an image, is defined. */ - rc = CDK_Inv_Packet; - goto error; - } - - p++; - len--; - - if (len >= pktlen) { - rc = CDK_Inv_Packet; - goto error; - } - - attr->attrib_img = cdk_calloc(1, len); - if (!attr->attrib_img) { - rc = CDK_Out_Of_Core; - goto error; - } - - attr->attrib_len = len; - memcpy(attr->attrib_img, p, len); - cdk_free(buf); - return rc; - - error: - cdk_free(buf); - return rc; -} - - -static cdk_error_t -read_user_id(cdk_stream_t inp, size_t pktlen, cdk_pkt_userid_t user_id) -{ - size_t nread; - cdk_error_t rc; - - if (!inp || !user_id) - return CDK_Inv_Value; - if (!pktlen) - return CDK_Inv_Packet; - - if (DEBUG_PKT) - _gnutls_write_log("read_user_id: %lu octets\n", - (unsigned long) pktlen); - - user_id->len = pktlen; - rc = stream_read(inp, user_id->name, pktlen, &nread); - if (rc) - return rc; - if (nread != pktlen) - return CDK_Inv_Packet; - user_id->name[nread] = '\0'; - return rc; -} - - -#define MAX_PACKET_LEN (1<<24) - - -static cdk_error_t -read_subpkt(cdk_stream_t inp, cdk_subpkt_t * r_ctx, size_t * r_nbytes) -{ - int c, c1; - size_t size, nread = 0, n; - cdk_subpkt_t node; - cdk_error_t rc; - - if (!inp || !r_nbytes) - return CDK_Inv_Value; - - if (DEBUG_PKT) - _gnutls_write_log("read_subpkt:\n"); - - n = 0; - *r_nbytes = 0; - c = cdk_stream_getc(inp); - n++; - - if (c == 255) { - size = read_32(inp); - if (size == (u32)-1) - return CDK_Inv_Packet; - - n += 4; - } else if (c >= 192 && c < 255) { - c1 = cdk_stream_getc(inp); - if (c1 == EOF) - return CDK_Inv_Packet; - - n++; - if (c1 == 0) - return 0; - size = ((c - 192) << 8) + c1 + 192; - } else if (c < 192) - size = c; - else - return CDK_Inv_Packet; - - if (size >= MAX_PACKET_LEN) { - return CDK_Inv_Packet; - } - - node = cdk_subpkt_new(size); - if (!node) - return CDK_Out_Of_Core; - node->size = size; - node->type = cdk_stream_getc(inp); - if (DEBUG_PKT) - _gnutls_write_log(" %d octets %d type\n", node->size, - node->type); - n++; - node->size--; - rc = stream_read(inp, node->d, node->size, &nread); - if (rc) { - cdk_subpkt_free(node); - return rc; - } - - n += nread; - *r_nbytes = n; - if (!*r_ctx) - *r_ctx = node; - else - cdk_subpkt_add(*r_ctx, node); - return rc; -} - - -static cdk_error_t -read_onepass_sig(cdk_stream_t inp, size_t pktlen, - cdk_pkt_onepass_sig_t sig) -{ - if (!inp || !sig) - return CDK_Inv_Value; - - if (DEBUG_PKT) - _gnutls_write_log("read_onepass_sig: %d octets\n", - (int) pktlen); - - if (pktlen != 13) - return CDK_Inv_Packet; - sig->version = cdk_stream_getc(inp); - if (sig->version != 3) - return CDK_Inv_Packet_Ver; - sig->sig_class = cdk_stream_getc(inp); - sig->digest_algo = _pgp_hash_algo_to_gnutls(cdk_stream_getc(inp)); - sig->pubkey_algo = _pgp_pub_algo_to_cdk(cdk_stream_getc(inp)); - sig->keyid[0] = read_32(inp); - sig->keyid[1] = read_32(inp); - sig->last = cdk_stream_getc(inp); - return 0; -} - - -static cdk_error_t parse_sig_subpackets(cdk_pkt_signature_t sig) -{ - cdk_subpkt_t node; - - /* Setup the standard packet entries, so we can use V4 - signatures similar to V3. */ - for (node = sig->unhashed; node; node = node->next) { - if (node->type == CDK_SIGSUBPKT_ISSUER && node->size >= 8) { - sig->keyid[0] = _cdk_buftou32(node->d); - sig->keyid[1] = _cdk_buftou32(node->d + 4); - } else if (node->type == CDK_SIGSUBPKT_EXPORTABLE - && node->d[0] == 0) { - /* Sometimes this packet might be placed in the unhashed area */ - sig->flags.exportable = 0; - } - } - for (node = sig->hashed; node; node = node->next) { - if (node->type == CDK_SIGSUBPKT_SIG_CREATED - && node->size >= 4) - sig->timestamp = _cdk_buftou32(node->d); - else if (node->type == CDK_SIGSUBPKT_SIG_EXPIRE - && node->size >= 4) { - sig->expiredate = _cdk_buftou32(node->d); - if (sig->expiredate > 0 - && sig->expiredate < (u32) gnutls_time(NULL)) - sig->flags.expired = 1; - } else if (node->type == CDK_SIGSUBPKT_POLICY) - sig->flags.policy_url = 1; - else if (node->type == CDK_SIGSUBPKT_NOTATION) - sig->flags.notation = 1; - else if (node->type == CDK_SIGSUBPKT_REVOCABLE - && node->d[0] == 0) - sig->flags.revocable = 0; - else if (node->type == CDK_SIGSUBPKT_EXPORTABLE - && node->d[0] == 0) - sig->flags.exportable = 0; - } - if (sig->sig_class == 0x1F) { - cdk_desig_revoker_t r, rnode; - - for (node = sig->hashed; node; node = node->next) { - if (node->type == CDK_SIGSUBPKT_REV_KEY) { - if (node->size < 22) - continue; - rnode = cdk_calloc(1, sizeof *rnode); - if (!rnode) - return CDK_Out_Of_Core; - rnode->r_class = node->d[0]; - rnode->algid = node->d[1]; - memcpy(rnode->fpr, node->d + 2, - KEY_FPR_LEN); - if (!sig->revkeys) - sig->revkeys = rnode; - else { - for (r = sig->revkeys; r->next; - r = r->next); - r->next = rnode; - } - } - } - } - - return 0; -} - - -static cdk_error_t -read_signature(cdk_stream_t inp, size_t pktlen, cdk_pkt_signature_t sig) -{ - size_t nbytes; - size_t i, nsig; - ssize_t size; - cdk_error_t rc; - - if (!inp || !sig) - return gnutls_assert_val(CDK_Inv_Value); - - if (DEBUG_PKT) - _gnutls_write_log("read_signature: %d octets\n", - (int) pktlen); - - if (pktlen < 16) - return gnutls_assert_val(CDK_Inv_Packet); - sig->version = cdk_stream_getc(inp); - if (sig->version < 2 || sig->version > 4) - return gnutls_assert_val(CDK_Inv_Packet_Ver); - - sig->flags.exportable = 1; - sig->flags.revocable = 1; - - if (sig->version < 4) { - if (cdk_stream_getc(inp) != 5) - return gnutls_assert_val(CDK_Inv_Packet); - sig->sig_class = cdk_stream_getc(inp); - sig->timestamp = read_32(inp); - sig->keyid[0] = read_32(inp); - sig->keyid[1] = read_32(inp); - sig->pubkey_algo = - _pgp_pub_algo_to_cdk(cdk_stream_getc(inp)); - sig->digest_algo = - _pgp_hash_algo_to_gnutls(cdk_stream_getc(inp)); - sig->digest_start[0] = cdk_stream_getc(inp); - sig->digest_start[1] = cdk_stream_getc(inp); - nsig = cdk_pk_get_nsig(sig->pubkey_algo); - if (!nsig) - return gnutls_assert_val(CDK_Inv_Algo); - for (i = 0; i < nsig; i++) { - rc = read_mpi(inp, &sig->mpi[i], 0); - if (rc) - return gnutls_assert_val(rc); - } - } else { - sig->sig_class = cdk_stream_getc(inp); - sig->pubkey_algo = - _pgp_pub_algo_to_cdk(cdk_stream_getc(inp)); - sig->digest_algo = - _pgp_hash_algo_to_gnutls(cdk_stream_getc(inp)); - sig->hashed_size = read_16(inp); - size = sig->hashed_size; - sig->hashed = NULL; - while (size > 0) { - rc = read_subpkt(inp, &sig->hashed, &nbytes); - if (rc) - return gnutls_assert_val(rc); - size -= nbytes; - } - sig->unhashed_size = read_16(inp); - size = sig->unhashed_size; - sig->unhashed = NULL; - while (size > 0) { - rc = read_subpkt(inp, &sig->unhashed, &nbytes); - if (rc) - return gnutls_assert_val(rc); - size -= nbytes; - } - - rc = parse_sig_subpackets(sig); - if (rc) - return gnutls_assert_val(rc); - - sig->digest_start[0] = cdk_stream_getc(inp); - sig->digest_start[1] = cdk_stream_getc(inp); - nsig = cdk_pk_get_nsig(sig->pubkey_algo); - if (!nsig) - return gnutls_assert_val(CDK_Inv_Algo); - for (i = 0; i < nsig; i++) { - rc = read_mpi(inp, &sig->mpi[i], 0); - if (rc) - return gnutls_assert_val(rc); - } - } - - return 0; -} - - -static cdk_error_t -read_literal(cdk_stream_t inp, size_t pktlen, - cdk_pkt_literal_t * ret_pt, int is_partial) -{ - cdk_pkt_literal_t pt = *ret_pt; - size_t nread = 0; - cdk_error_t rc; - - if (!inp || !pt) - return CDK_Inv_Value; - - if (DEBUG_PKT) - _gnutls_write_log("read_literal: %d octets\n", - (int) pktlen); - - pt->mode = cdk_stream_getc(inp); - if (pt->mode != 0x62 && pt->mode != 0x74 && pt->mode != 0x75) - return CDK_Inv_Packet; - if (cdk_stream_eof(inp)) - return CDK_Inv_Packet; - - pt->namelen = cdk_stream_getc(inp); - if (pt->namelen > 0) { - *ret_pt = pt = - cdk_realloc(pt, sizeof *pt + pt->namelen + 2); - if (!pt) - return CDK_Out_Of_Core; - pt->name = (char *) pt + sizeof(*pt); - rc = stream_read(inp, pt->name, pt->namelen, &nread); - if (rc) - return rc; - if ((int) nread != pt->namelen) - return CDK_Inv_Packet; - pt->name[pt->namelen] = '\0'; - } - pt->timestamp = read_32(inp); - pktlen = pktlen - 6 - pt->namelen; - if (is_partial) - _cdk_stream_set_blockmode(inp, pktlen); - pt->buf = inp; - pt->len = pktlen; - return 0; -} - - -/* Read an old packet CTB and return the length of the body. */ -static void -read_old_length(cdk_stream_t inp, int ctb, size_t * r_len, size_t * r_size) -{ - int llen = ctb & 0x03; - int c; - - if (llen == 0) { - c = cdk_stream_getc(inp); - if (c == EOF) - goto fail; - - *r_len = c; - (*r_size)++; - } else if (llen == 1) { - *r_len = read_16(inp); - if (*r_len == (u16)-1) - goto fail; - (*r_size) += 2; - } else if (llen == 2) { - *r_len = read_32(inp); - if (*r_len == (u32)-1) { - goto fail; - } - - (*r_size) += 4; - } else { - fail: - *r_len = 0; - *r_size = 0; - } -} - - -/* Read a new CTB and decode the body length. */ -static void -read_new_length(cdk_stream_t inp, - size_t * r_len, size_t * r_size, size_t * r_partial) -{ - int c, c1; - - c = cdk_stream_getc(inp); - if (c == EOF) - return; - - (*r_size)++; - if (c < 192) - *r_len = c; - else if (c >= 192 && c <= 223) { - c1 = cdk_stream_getc(inp); - if (c1 == EOF) - return; - - (*r_size)++; - *r_len = ((c - 192) << 8) + c1 + 192; - } else if (c == 255) { - c1 = read_32(inp); - if (c1 == -1) { - return; - } - - *r_len = c1; - (*r_size) += 4; - } else { - *r_len = 1 << (c & 0x1f); - *r_partial = 1; - } -} - - -/* Skip the current packet body. */ -static cdk_error_t skip_packet(cdk_stream_t inp, size_t pktlen) -{ - byte buf[BUFSIZE]; - size_t nread = 0, buflen = DIM(buf); - - while (pktlen > 0) { - cdk_error_t rc; - rc = stream_read(inp, buf, pktlen > buflen ? buflen : pktlen, - &nread); - if (rc) - return rc; - pktlen -= nread; - } - - assert(pktlen == 0); - return 0; -} - -/** - * cdk_pkt_read: - * @inp: the input stream - * @pkt: allocated packet handle to store the packet - * - * Parse the next packet on the @inp stream and return its contents in @pkt. - **/ -cdk_error_t cdk_pkt_read(cdk_stream_t inp, cdk_packet_t pkt, unsigned public) -{ - int ctb, is_newctb; - int pkttype; - size_t pktlen = 0, pktsize = 0, is_partial = 0; - cdk_error_t rc; - - if (!inp || !pkt) - return CDK_Inv_Value; - - ctb = cdk_stream_getc(inp); - if (cdk_stream_eof(inp) || ctb == EOF) - return CDK_EOF; - else if (!ctb) - return gnutls_assert_val(CDK_Inv_Packet); - - pktsize++; - if (!(ctb & 0x80)) { - _cdk_log_info("cdk_pkt_read: no openpgp data found. " - "(ctb=%02X; fpos=%02X)\n", (int) ctb, - (int) cdk_stream_tell(inp)); - return gnutls_assert_val(CDK_Inv_Packet); - } - - if (ctb & 0x40) { /* RFC2440 packet format. */ - pkttype = ctb & 0x3f; - is_newctb = 1; - } else { /* the old RFC1991 packet format. */ - - pkttype = ctb & 0x3f; - pkttype >>= 2; - is_newctb = 0; - } - - if (pkttype > 63) { - _cdk_log_info("cdk_pkt_read: unknown type %d\n", pkttype); - return gnutls_assert_val(CDK_Inv_Packet); - } - - if (is_newctb) - read_new_length(inp, &pktlen, &pktsize, &is_partial); - else - read_old_length(inp, ctb, &pktlen, &pktsize); - - /* enforce limits to ensure that the following calculations - * do not overflow */ - if (pktlen >= MAX_PACKET_LEN || pktsize >= MAX_PACKET_LEN) { - _cdk_log_info("cdk_pkt_read: too long packet\n"); - return gnutls_assert_val(CDK_Inv_Packet); - } - - pkt->pkttype = pkttype; - pkt->pktlen = pktlen; - pkt->pktsize = pktsize + pktlen; - pkt->old_ctb = is_newctb ? 0 : 1; - - switch (pkt->pkttype) { - case CDK_PKT_ATTRIBUTE: -#define NAME_SIZE (pkt->pktlen + 16 + 1) - pkt->pkt.user_id = cdk_calloc(1, sizeof *pkt->pkt.user_id - + NAME_SIZE); - if (!pkt->pkt.user_id) - return gnutls_assert_val(CDK_Out_Of_Core); - pkt->pkt.user_id->name = - (char *) pkt->pkt.user_id + sizeof(*pkt->pkt.user_id); - - rc = read_attribute(inp, pktlen, pkt->pkt.user_id, - NAME_SIZE); - pkt->pkttype = CDK_PKT_ATTRIBUTE; - if (rc) - return gnutls_assert_val(rc); - break; - - case CDK_PKT_USER_ID: - - pkt->pkt.user_id = cdk_calloc(1, sizeof *pkt->pkt.user_id - + pkt->pktlen + 1); - if (!pkt->pkt.user_id) - return gnutls_assert_val(CDK_Out_Of_Core); - pkt->pkt.user_id->name = - (char *) pkt->pkt.user_id + sizeof(*pkt->pkt.user_id); - rc = read_user_id(inp, pktlen, pkt->pkt.user_id); - if (rc) - return gnutls_assert_val(rc); - break; - - case CDK_PKT_PUBLIC_KEY: - pkt->pkt.public_key = - cdk_calloc(1, sizeof *pkt->pkt.public_key); - if (!pkt->pkt.public_key) - return gnutls_assert_val(CDK_Out_Of_Core); - rc = read_public_key(inp, pktlen, pkt->pkt.public_key); - if (rc) - return gnutls_assert_val(rc); - break; - - case CDK_PKT_PUBLIC_SUBKEY: - pkt->pkt.public_key = - cdk_calloc(1, sizeof *pkt->pkt.public_key); - if (!pkt->pkt.public_key) - return gnutls_assert_val(CDK_Out_Of_Core); - rc = read_public_subkey(inp, pktlen, pkt->pkt.public_key); - if (rc) - return gnutls_assert_val(rc); - break; - - case CDK_PKT_SECRET_KEY: - if (public) { - /* read secret key when expecting public */ - return gnutls_assert_val(CDK_Inv_Packet); - } - pkt->pkt.secret_key = - cdk_calloc(1, sizeof *pkt->pkt.secret_key); - if (!pkt->pkt.secret_key) - return gnutls_assert_val(CDK_Out_Of_Core); - pkt->pkt.secret_key->pk = cdk_calloc(1, - sizeof *pkt->pkt. - secret_key->pk); - if (!pkt->pkt.secret_key->pk) - return gnutls_assert_val(CDK_Out_Of_Core); - rc = read_secret_key(inp, pktlen, pkt->pkt.secret_key); - if (rc) - return gnutls_assert_val(rc); - break; - - case CDK_PKT_SECRET_SUBKEY: - if (public) { - /* read secret key when expecting public */ - return gnutls_assert_val(CDK_Inv_Packet); - } - pkt->pkt.secret_key = - cdk_calloc(1, sizeof *pkt->pkt.secret_key); - if (!pkt->pkt.secret_key) - return gnutls_assert_val(CDK_Out_Of_Core); - pkt->pkt.secret_key->pk = cdk_calloc(1, - sizeof *pkt->pkt. - secret_key->pk); - if (!pkt->pkt.secret_key->pk) - return gnutls_assert_val(CDK_Out_Of_Core); - rc = read_secret_subkey(inp, pktlen, pkt->pkt.secret_key); - if (rc) - return gnutls_assert_val(rc); - break; - - case CDK_PKT_LITERAL: - pkt->pkt.literal = cdk_calloc(1, sizeof *pkt->pkt.literal); - if (!pkt->pkt.literal) - return gnutls_assert_val(CDK_Out_Of_Core); - rc = read_literal(inp, pktlen, &pkt->pkt.literal, - is_partial); - if (rc) - return gnutls_assert_val(rc); - break; - - case CDK_PKT_ONEPASS_SIG: - pkt->pkt.onepass_sig = - cdk_calloc(1, sizeof *pkt->pkt.onepass_sig); - if (!pkt->pkt.onepass_sig) - return gnutls_assert_val(CDK_Out_Of_Core); - rc = read_onepass_sig(inp, pktlen, pkt->pkt.onepass_sig); - if (rc) - return gnutls_assert_val(rc); - break; - - case CDK_PKT_SIGNATURE: - pkt->pkt.signature = - cdk_calloc(1, sizeof *pkt->pkt.signature); - if (!pkt->pkt.signature) - return gnutls_assert_val(CDK_Out_Of_Core); - rc = read_signature(inp, pktlen, pkt->pkt.signature); - if (rc) - return gnutls_assert_val(rc); - break; - - case CDK_PKT_PUBKEY_ENC: - pkt->pkt.pubkey_enc = - cdk_calloc(1, sizeof *pkt->pkt.pubkey_enc); - if (!pkt->pkt.pubkey_enc) - return gnutls_assert_val(CDK_Out_Of_Core); - rc = read_pubkey_enc(inp, pktlen, pkt->pkt.pubkey_enc); - if (rc) - return gnutls_assert_val(rc); - break; - - case CDK_PKT_COMPRESSED: - pkt->pkt.compressed = - cdk_calloc(1, sizeof *pkt->pkt.compressed); - if (!pkt->pkt.compressed) - return gnutls_assert_val(CDK_Out_Of_Core); - rc = read_compressed(inp, pktlen, pkt->pkt.compressed); - if (rc) - return gnutls_assert_val(rc); - break; - - case CDK_PKT_MDC: - pkt->pkt.mdc = cdk_calloc(1, sizeof *pkt->pkt.mdc); - if (!pkt->pkt.mdc) - return gnutls_assert_val(CDK_Out_Of_Core); - rc = read_mdc(inp, pkt->pkt.mdc); - if (rc) - return gnutls_assert_val(rc); - break; - - default: - /* Skip all packets we don't understand */ - rc = skip_packet(inp, pktlen); - if (rc) - return gnutls_assert_val(rc); - break; - } - - return rc; -} diff --git a/lib/opencdk/seskey.c b/lib/opencdk/seskey.c deleted file mode 100644 index 77fbd1f9d6..0000000000 --- a/lib/opencdk/seskey.c +++ /dev/null @@ -1,95 +0,0 @@ -/* seskey.c - Session key routines - * Copyright (C) 1998-2012 Free Software Foundation, Inc. - * - * Author: Timo Schulz - * - * This file is part of OpenCDK. - * - * The OpenCDK 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> - -#include "opencdk.h" -#include "main.h" -#include "packet.h" -#include <algorithms.h> - -/** - * cdk_s2k_new: - * @ret_s2k: output for the new S2K object - * @mode: the S2K mode (simple, salted, iter+salted) - * @digest_algo: the hash algorithm - * @salt: random salt - * - * Create a new S2K object with the given parameter. - * The @salt parameter must be always 8 octets. - **/ -cdk_error_t -cdk_s2k_new(cdk_s2k_t * ret_s2k, int mode, int digest_algo, - const byte * salt) -{ - cdk_s2k_t s2k; - - if (!ret_s2k) - return CDK_Inv_Value; - - if (mode != 0x00 && mode != 0x01 && mode != 0x03) - return CDK_Inv_Mode; - - if (_gnutls_hash_get_algo_len(mac_to_entry(digest_algo)) <= 0) - return CDK_Inv_Algo; - - s2k = cdk_calloc(1, sizeof *s2k); - if (!s2k) - return CDK_Out_Of_Core; - s2k->mode = mode; - s2k->hash_algo = digest_algo; - if (salt) - memcpy(s2k->salt, salt, 8); - *ret_s2k = s2k; - return 0; -} - - -/** - * cdk_s2k_free: - * @s2k: the S2K object - * - * Release the given S2K object. - **/ -void cdk_s2k_free(cdk_s2k_t s2k) -{ - cdk_free(s2k); -} - - -/* Make a copy of the source s2k into R_DST. */ -cdk_error_t _cdk_s2k_copy(cdk_s2k_t * r_dst, cdk_s2k_t src) -{ - cdk_s2k_t dst; - cdk_error_t err; - - err = cdk_s2k_new(&dst, src->mode, src->hash_algo, src->salt); - if (err) - return err; - dst->count = src->count; - *r_dst = dst; - - return 0; -} diff --git a/lib/opencdk/sig-check.c b/lib/opencdk/sig-check.c deleted file mode 100644 index 935895fc5f..0000000000 --- a/lib/opencdk/sig-check.c +++ /dev/null @@ -1,601 +0,0 @@ -/* sig-check.c - Check signatures - * Copyright (C) 1998-2012 Free Software Foundation, Inc. - * - * Author: Timo Schulz - * - * This file is part of OpenCDK. - * - * The OpenCDK 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include "gnutls_int.h" -#include <algorithms.h> - -#include "opencdk.h" -#include "main.h" -#include "packet.h" - -/* Hash all multi precision integers of the key PK with the given - message digest context MD. */ -static int hash_mpibuf(cdk_pubkey_t pk, digest_hd_st * md, int usefpr) -{ - byte buf[MAX_MPI_BYTES]; /* FIXME: do not use hardcoded length. */ - size_t nbytes; - size_t i, npkey; - int err; - - /* We have to differ between two modes for v3 keys. To form the - fingerprint, we hash the MPI values without the length prefix. - But if we calculate the hash for verifying/signing we use all data. */ - npkey = cdk_pk_get_npkey(pk->pubkey_algo); - for (i = 0; i < npkey; i++) { - nbytes = MAX_MPI_BYTES; - err = _gnutls_mpi_print_pgp(pk->mpi[i], buf, &nbytes); - - if (err < 0) { - gnutls_assert(); - return map_gnutls_error(err); - } - - if (!usefpr || pk->version == 4) - _gnutls_hash(md, buf, nbytes); - else /* without the prefix. */ - _gnutls_hash(md, buf + 2, nbytes - 2); - } - return 0; -} - - -/* Hash an entire public key PK with the given message digest context - MD. The @usefpr param is only valid for version 3 keys because of - the different way to calculate the fingerprint. */ -cdk_error_t -_cdk_hash_pubkey(cdk_pubkey_t pk, digest_hd_st * md, int usefpr) -{ - byte buf[12]; - size_t i, n, npkey; - - if (!pk || !md) - return CDK_Inv_Value; - - if (usefpr && pk->version < 4 && is_RSA(pk->pubkey_algo)) - return hash_mpibuf(pk, md, 1); - - /* The version 4 public key packet does not have the 2 octets for - the expiration date. */ - n = pk->version < 4 ? 8 : 6; - npkey = cdk_pk_get_npkey(pk->pubkey_algo); - for (i = 0; i < npkey; i++) - n = n + (_gnutls_mpi_get_nbits(pk->mpi[i]) + 7) / 8 + 2; - - i = 0; - buf[i++] = 0x99; - buf[i++] = n >> 8; - buf[i++] = n >> 0; - buf[i++] = pk->version; - buf[i++] = pk->timestamp >> 24; - buf[i++] = pk->timestamp >> 16; - buf[i++] = pk->timestamp >> 8; - buf[i++] = pk->timestamp >> 0; - - if (pk->version < 4) { - u16 a = 0; - - /* Convert the expiration date into days. */ - if (pk->expiredate) - a = (u16) ((pk->expiredate - - pk->timestamp) / 86400L); - buf[i++] = a >> 8; - buf[i++] = a; - } - buf[i++] = pk->pubkey_algo; - _gnutls_hash(md, buf, i); - return hash_mpibuf(pk, md, 0); -} - - -/* Hash the user ID @uid with the given message digest @md. - Use openpgp mode if @is_v4 is 1. */ -cdk_error_t -_cdk_hash_userid(cdk_pkt_userid_t uid, int is_v4, digest_hd_st * md) -{ - const byte *data; - byte buf[5]; - u32 dlen; - - if (!uid || !md) - return CDK_Inv_Value; - - if (!is_v4) { - _gnutls_hash(md, (byte *) uid->name, uid->len); - return 0; - } - - dlen = uid->attrib_img ? uid->attrib_len : uid->len; - data = uid->attrib_img ? uid->attrib_img : (byte *) uid->name; - buf[0] = uid->attrib_img ? 0xD1 : 0xB4; - buf[1] = dlen >> 24; - buf[2] = dlen >> 16; - buf[3] = dlen >> 8; - buf[4] = dlen >> 0; - _gnutls_hash(md, buf, 5); - _gnutls_hash(md, data, dlen); - return 0; -} - - -/* Hash all parts of the signature which are needed to derive - the correct message digest to verify the sig. */ -cdk_error_t _cdk_hash_sig_data(cdk_pkt_signature_t sig, digest_hd_st * md) -{ - byte buf[4]; - byte tmp; - - if (!sig || !md) - return CDK_Inv_Value; - - if (sig->version == 4) - _gnutls_hash(md, &sig->version, 1); - - _gnutls_hash(md, &sig->sig_class, 1); - if (sig->version < 4) { - buf[0] = sig->timestamp >> 24; - buf[1] = sig->timestamp >> 16; - buf[2] = sig->timestamp >> 8; - buf[3] = sig->timestamp >> 0; - _gnutls_hash(md, buf, 4); - } else { - size_t n; - - tmp = _cdk_pub_algo_to_pgp(sig->pubkey_algo); - _gnutls_hash(md, &tmp, 1); - tmp = _gnutls_hash_algo_to_pgp(sig->digest_algo); - _gnutls_hash(md, &tmp, 1); - if (sig->hashed != NULL) { - byte *p = - _cdk_subpkt_get_array(sig->hashed, 0, &n); - if (p == NULL) - return gnutls_assert_val(CDK_Inv_Value); - - buf[0] = n >> 8; - buf[1] = n >> 0; - _gnutls_hash(md, buf, 2); - _gnutls_hash(md, p, n); - cdk_free(p); - sig->hashed_size = n; - n = sig->hashed_size + 6; - } else { - tmp = 0x00; - _gnutls_hash(md, &tmp, 1); - _gnutls_hash(md, &tmp, 1); - n = 6; - } - _gnutls_hash(md, &sig->version, 1); - tmp = 0xff; - _gnutls_hash(md, &tmp, 1); - buf[0] = n >> 24; - buf[1] = n >> 16; - buf[2] = n >> 8; - buf[3] = n >> 0; - _gnutls_hash(md, buf, 4); - } - return 0; -} - - -/* Cache the signature result and store it inside the sig. */ -static void cache_sig_result(cdk_pkt_signature_t sig, int res) -{ - sig->flags.checked = 0; - sig->flags.valid = 0; - if (res == 0) { - sig->flags.checked = 1; - sig->flags.valid = 1; - } else if (res == CDK_Bad_Sig) { - sig->flags.checked = 1; - sig->flags.valid = 0; - } -} - - -/* Check the given signature @sig with the public key @pk. - Use the digest handle @digest. */ -cdk_error_t -_cdk_sig_check(cdk_pubkey_t pk, cdk_pkt_signature_t sig, - digest_hd_st * digest, int *r_expired) -{ - cdk_error_t rc; - byte md[MAX_DIGEST_LEN]; - time_t cur_time = (u32) gnutls_time(NULL); - - if (!pk || !sig || !digest) { - gnutls_assert(); - return CDK_Inv_Value; - } - - if (sig->flags.checked) - return sig->flags.valid ? 0 : CDK_Bad_Sig; - if (!KEY_CAN_SIGN(pk->pubkey_algo)) - return CDK_Inv_Algo; - if (pk->timestamp > sig->timestamp || pk->timestamp > cur_time) - return CDK_Time_Conflict; - - if (r_expired && pk->expiredate - && (pk->expiredate + pk->timestamp) > cur_time) - *r_expired = 1; - - _cdk_hash_sig_data(sig, digest); - _gnutls_hash_output(digest, md); - - if (md[0] != sig->digest_start[0] || md[1] != sig->digest_start[1]) { - gnutls_assert(); - return CDK_Chksum_Error; - } - - rc = cdk_pk_verify(pk, sig, md); - cache_sig_result(sig, rc); - return rc; -} - - -/* Check the given key signature. - @knode is the key node and @snode the signature node. */ -cdk_error_t -_cdk_pk_check_sig(cdk_keydb_hd_t keydb, - cdk_kbnode_t knode, cdk_kbnode_t snode, int *is_selfsig, - char **ret_uid) -{ - digest_hd_st md; - int err; - cdk_pubkey_t pk; - cdk_pkt_signature_t sig; - cdk_kbnode_t node; - cdk_error_t rc = 0; - int is_expired; - - if (!knode || !snode) { - gnutls_assert(); - return CDK_Inv_Value; - } - - if (is_selfsig) - *is_selfsig = 0; - if ((knode->pkt->pkttype != CDK_PKT_PUBLIC_KEY && - knode->pkt->pkttype != CDK_PKT_PUBLIC_SUBKEY) || - snode->pkt->pkttype != CDK_PKT_SIGNATURE) { - gnutls_assert(); - return CDK_Inv_Value; - } - pk = knode->pkt->pkt.public_key; - sig = snode->pkt->pkt.signature; - - err = _gnutls_hash_init(&md, mac_to_entry(sig->digest_algo)); - if (err < 0) { - gnutls_assert(); - return map_gnutls_error(err); - } - - is_expired = 0; - if (sig->sig_class == 0x20) { /* key revocation */ - cdk_kbnode_hash(knode, &md, 0, 0, 0); - rc = _cdk_sig_check(pk, sig, &md, &is_expired); - } else if (sig->sig_class == 0x28) { /* subkey revocation */ - node = - cdk_kbnode_find_prev(knode, snode, - CDK_PKT_PUBLIC_SUBKEY); - if (!node) { /* no subkey for subkey revocation packet */ - gnutls_assert(); - rc = CDK_Error_No_Key; - goto fail; - } - cdk_kbnode_hash(knode, &md, 0, 0, 0); - cdk_kbnode_hash(node, &md, 0, 0, 0); - rc = _cdk_sig_check(pk, sig, &md, &is_expired); - } else if (sig->sig_class == 0x18 || sig->sig_class == 0x19) { /* primary/secondary key binding */ - node = - cdk_kbnode_find_prev(knode, snode, - CDK_PKT_PUBLIC_SUBKEY); - if (!node) { /* no subkey for subkey binding packet */ - gnutls_assert(); - rc = CDK_Error_No_Key; - goto fail; - } - cdk_kbnode_hash(knode, &md, 0, 0, 0); - cdk_kbnode_hash(node, &md, 0, 0, 0); - rc = _cdk_sig_check(pk, sig, &md, &is_expired); - } else if (sig->sig_class == 0x1F) { /* direct key signature */ - cdk_kbnode_hash(knode, &md, 0, 0, 0); - rc = _cdk_sig_check(pk, sig, &md, &is_expired); - } else { /* all other classes */ - cdk_pkt_userid_t uid; - node = cdk_kbnode_find_prev(knode, snode, CDK_PKT_USER_ID); - if (!node) { /* no user ID for key signature packet */ - gnutls_assert(); - rc = CDK_Error_No_Key; - goto fail; - } - - uid = node->pkt->pkt.user_id; - if (ret_uid) { - *ret_uid = uid->name; - } - cdk_kbnode_hash(knode, &md, 0, 0, 0); - cdk_kbnode_hash(node, &md, sig->version == 4, 0, 0); - - if (pk->keyid[0] == sig->keyid[0] - && pk->keyid[1] == sig->keyid[1]) { - rc = _cdk_sig_check(pk, sig, &md, &is_expired); - if (is_selfsig) - *is_selfsig = 1; - } else if (keydb != NULL) { - cdk_pubkey_t sig_pk; - rc = cdk_keydb_get_pk(keydb, sig->keyid, &sig_pk); - if (!rc) - rc = _cdk_sig_check(sig_pk, sig, &md, - &is_expired); - cdk_pk_release(sig_pk); - } - } - fail: - _gnutls_hash_deinit(&md, NULL); - return rc; -} - -struct verify_uid { - const char *name; - int nsigs; - struct verify_uid *next; -}; - -static int -uid_list_add_sig(struct verify_uid **list, const char *uid, - unsigned int flag) -{ - if (*list == NULL) { - *list = cdk_calloc(1, sizeof(struct verify_uid)); - if (*list == NULL) - return CDK_Out_Of_Core; - (*list)->name = uid; - - if (flag != 0) - (*list)->nsigs++; - } else { - struct verify_uid *p, *prev_p = NULL; - int found = 0; - - p = *list; - - while (p != NULL) { - if (strcmp(uid, p->name) == 0) { - found = 1; - break; - } - prev_p = p; - p = p->next; - } - - if (found == 0) { /* not found add to the last */ - prev_p->next = - cdk_calloc(1, sizeof(struct verify_uid)); - if (prev_p->next == NULL) - return CDK_Out_Of_Core; - prev_p->next->name = uid; - if (flag != 0) - prev_p->next->nsigs++; - } else { /* found... increase sigs */ - if (flag != 0) - p->nsigs++; - } - } - - return CDK_Success; -} - -static void uid_list_free(struct verify_uid *list) -{ - struct verify_uid *p, *p1; - - p = list; - while (p != NULL) { - p1 = p->next; - cdk_free(p); - p = p1; - } -} - -/* returns non (0) if all UIDs in the list have at least one - * signature. If the list is empty or no signatures are present - * a (0) value is returned. - */ -static int uid_list_all_signed(struct verify_uid *list) -{ - struct verify_uid *p; - - if (list == NULL) - return 0; - - p = list; - while (p != NULL) { - if (p->nsigs == 0) { - return 0; - } - p = p->next; - } - return 1; /* all signed */ -} - -/** - * cdk_pk_check_sigs: - * @key: the public key - * @hd: an optinal key database handle - * @r_status: variable to store the status of the key - * - * Check all signatures. When no key is available for checking, the - * sigstat is marked as 'NOKEY'. The @r_status contains the key flags - * which are or-ed or (0) when there are no flags. - **/ -cdk_error_t -cdk_pk_check_sigs(cdk_kbnode_t key, cdk_keydb_hd_t keydb, int *r_status) -{ - cdk_pkt_signature_t sig; - cdk_kbnode_t node; - cdk_error_t rc; - u32 keyid; - int key_status, is_selfsig = 0; - struct verify_uid *uid_list = NULL; - char *uid_name = NULL; - - if (!key || !r_status) { - gnutls_assert(); - return CDK_Inv_Value; - } - - *r_status = 0; - node = cdk_kbnode_find(key, CDK_PKT_PUBLIC_KEY); - if (!node) { - gnutls_assert(); - return CDK_Error_No_Key; - } - - key_status = 0; - /* Continue with the signature check but adjust the - key status flags accordingly. */ - if (node->pkt->pkt.public_key->is_revoked) - key_status |= CDK_KEY_REVOKED; - if (node->pkt->pkt.public_key->has_expired) - key_status |= CDK_KEY_EXPIRED; - rc = 0; - - keyid = cdk_pk_get_keyid(node->pkt->pkt.public_key, NULL); - for (node = key; node; node = node->next) { - if (node->pkt->pkttype != CDK_PKT_SIGNATURE) - continue; - sig = node->pkt->pkt.signature; - rc = _cdk_pk_check_sig(keydb, key, node, &is_selfsig, - &uid_name); - - if (rc && rc != CDK_Error_No_Key) { - /* It might be possible that a single signature has been - corrupted, thus we do not consider it a problem when - one ore more signatures are bad. But at least the self - signature has to be valid. */ - if (is_selfsig) { - key_status |= CDK_KEY_INVALID; - break; - } - } - - _cdk_log_debug("signature %s: signer %08X keyid %08X\n", - rc == CDK_Bad_Sig ? "BAD" : "good", - (unsigned int) sig->keyid[1], - (unsigned int) keyid); - - if (IS_UID_SIG(sig) && uid_name != NULL) { - /* add every uid in the uid list. Only consider valid: - * - verification was ok - * - not a selfsig - */ - rc = uid_list_add_sig(&uid_list, uid_name, - (rc == CDK_Success - && is_selfsig == - 0) ? 1 : 0); - if (rc != CDK_Success) { - gnutls_assert(); - goto exit; - } - } - - } - - if (uid_list_all_signed(uid_list) == 0) - key_status |= CDK_KEY_NOSIGNER; - *r_status = key_status; - if (rc == CDK_Error_No_Key) - rc = 0; - - exit: - uid_list_free(uid_list); - return rc; -} - - -/** - * cdk_pk_check_self_sig: - * @key: the key node - * @r_status: output the status of the key. - * - * A convenient function to make sure the key is valid. - * Valid means the self signature is ok. - **/ -cdk_error_t cdk_pk_check_self_sig(cdk_kbnode_t key, int *r_status) -{ - cdk_pkt_signature_t sig; - cdk_kbnode_t node; - cdk_error_t rc; - u32 keyid[2], sigid[2]; - int is_selfsig, sig_ok; - cdk_kbnode_t p, ctx = NULL; - cdk_packet_t pkt; - - if (!key || !r_status) - return CDK_Inv_Value; - - cdk_pk_get_keyid(key->pkt->pkt.public_key, keyid); - - while ((p = cdk_kbnode_walk(key, &ctx, 0))) { - pkt = cdk_kbnode_get_packet(p); - if (pkt->pkttype != CDK_PKT_PUBLIC_SUBKEY - && pkt->pkttype != CDK_PKT_PUBLIC_KEY) - continue; - - /* FIXME: we should set expire/revoke here also but callers - expect CDK_KEY_VALID=0 if the key is okay. */ - sig_ok = 0; - for (node = p; node; node = node->next) { - if (node->pkt->pkttype != CDK_PKT_SIGNATURE) - continue; - sig = node->pkt->pkt.signature; - - cdk_sig_get_keyid(sig, sigid); - if (sigid[0] != keyid[0] || sigid[1] != keyid[1]) - continue; - /* FIXME: Now we check all self signatures. */ - rc = _cdk_pk_check_sig(NULL, p, node, &is_selfsig, - NULL); - if (rc) { - *r_status = CDK_KEY_INVALID; - return rc; - } else /* For each valid self sig we increase this counter. */ - sig_ok++; - } - - /* A key without a self signature is not valid. At least one - * signature for the given key has to be found. - */ - if (!sig_ok) { - *r_status = CDK_KEY_INVALID; - return CDK_General_Error; - } - } - - /* No flags indicate a valid key. */ - *r_status = CDK_KEY_VALID; - - return 0; -} diff --git a/lib/opencdk/stream.c b/lib/opencdk/stream.c deleted file mode 100644 index 496115aa3e..0000000000 --- a/lib/opencdk/stream.c +++ /dev/null @@ -1,1471 +0,0 @@ -/* stream.c - The stream implementation - * Copyright (C) 2002-2012 Free Software Foundation, Inc. - * - * Author: Timo Schulz - * - * This file is part of OpenCDK. - * - * The OpenCDK 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <assert.h> -#include <stdio.h> -#include <sys/stat.h> -#include <string.h> -#include <stdlib.h> -#include <errno.h> -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include "opencdk.h" -#include "main.h" -#include "filters.h" -#include "stream.h" -#include "types.h" - -/* This is the maximal amount of bytes we map. */ -#define MAX_MAP_SIZE 16777216 - -static cdk_error_t stream_flush(cdk_stream_t s); -static cdk_error_t stream_filter_write(cdk_stream_t s); -static int stream_cache_flush(cdk_stream_t s, FILE * fp); -struct stream_filter_s *filter_add(cdk_stream_t s, filter_fnct_t fnc, - int type); - - -/* FIXME: The read/write/putc/getc function cannot directly - return an error code. It is stored in an error variable - inside the string. Right now there is no code to - return the error code or to reset it. */ - -/** - * cdk_stream_open: - * @file: The file to open - * @ret_s: The new STREAM object - * - * Creates a new stream based on an existing file. The stream is - * opened in read-only mode. - **/ -cdk_error_t cdk_stream_open(const char *file, cdk_stream_t * ret_s) -{ - return _cdk_stream_open_mode(file, "rb", ret_s); -} - - -/* Helper function to allow to open a stream in different modes. */ -cdk_error_t -_cdk_stream_open_mode(const char *file, const char *mode, - cdk_stream_t * ret_s) -{ - cdk_stream_t s; - - if (!file || !ret_s) { - gnutls_assert(); - return CDK_Inv_Value; - } -#ifdef DEBUG_STREAM - _gnutls_read_log("open stream `%s'\n", file); -#endif - *ret_s = NULL; - s = cdk_calloc(1, sizeof *s); - if (!s) { - gnutls_assert(); - return CDK_Out_Of_Core; - } - s->fname = cdk_strdup(file); - if (!s->fname) { - cdk_free(s); - gnutls_assert(); - return CDK_Out_Of_Core; - } - s->fp = fopen(file, mode); - if (!s->fp) { - cdk_free(s->fname); - cdk_free(s); - gnutls_assert(); - return CDK_File_Error; - } -#ifdef DEBUG_STREAM - _gnutls_read_log("open stream fd=%d\n", fileno(s->fp)); -#endif - s->flags.write = 0; - *ret_s = s; - return 0; -} - - -/** - * cdk_stream_new_from_cbs: - * @cbs: the callback context with all user callback functions - * @opa: uint8_t handle which is passed to all callbacks. - * @ret_s: the allocated stream - * - * This function creates a stream which uses user callback - * for the core operations (open, close, read, write, seek). - */ -cdk_error_t -cdk_stream_new_from_cbs(cdk_stream_cbs_t cbs, void *opa, - cdk_stream_t * ret_s) -{ - cdk_stream_t s; - - if (!cbs || !opa || !ret_s) { - gnutls_assert(); - return CDK_Inv_Value; - } - - *ret_s = NULL; - s = cdk_calloc(1, sizeof *s); - if (!s) { - gnutls_assert(); - return CDK_Out_Of_Core; - } - - s->cbs.read = cbs->read; - s->cbs.write = cbs->write; - s->cbs.seek = cbs->seek; - s->cbs.release = cbs->release; - s->cbs.open = cbs->open; - s->cbs_hd = opa; - *ret_s = s; - - /* If there is a user callback for open, we need to call it - here because read/write expects an open stream. */ - if (s->cbs.open) - return s->cbs.open(s->cbs_hd); - return 0; -} - - -/** - * cdk_stream_new: - * @file: The name of the new file - * @ret_s: The new STREAM object - * - * Create a new stream into the given file. - **/ -cdk_error_t cdk_stream_new(const char *file, cdk_stream_t * ret_s) -{ - cdk_stream_t s; - - if (!ret_s) { - gnutls_assert(); - return CDK_Inv_Value; - } -#ifdef DEBUG_STREAM - _gnutls_read_log("new stream `%s'\n", file ? file : "[temp]"); -#endif - *ret_s = NULL; - s = cdk_calloc(1, sizeof *s); - if (!s) { - gnutls_assert(); - return CDK_Out_Of_Core; - } - s->flags.write = 1; - if (!file) - s->flags.temp = 1; - else { - s->fname = cdk_strdup(file); - if (!s->fname) { - cdk_free(s); - gnutls_assert(); - return CDK_Out_Of_Core; - } - } - s->fp = _cdk_tmpfile(); - if (!s->fp) { - cdk_free(s->fname); - cdk_free(s); - gnutls_assert(); - return CDK_File_Error; - } -#ifdef DEBUG_STREAM - _gnutls_read_log("new stream fd=%d\n", fileno(s->fp)); -#endif - *ret_s = s; - return 0; -} - -/** - * cdk_stream_create: - * @file: the filename - * @ret_s: the object - * - * Creates a new stream. - * The difference to cdk_stream_new is, that no filtering can be used with - * this kind of stream and everything is written directly to the stream. - **/ -cdk_error_t cdk_stream_create(const char *file, cdk_stream_t * ret_s) -{ - cdk_stream_t s; - - if (!file || !ret_s) { - gnutls_assert(); - return CDK_Inv_Value; - } -#ifdef DEBUG_STREAM - _gnutls_read_log("create stream `%s'\n", file); -#endif - *ret_s = NULL; - s = cdk_calloc(1, sizeof *s); - if (!s) { - gnutls_assert(); - return CDK_Out_Of_Core; - } - s->flags.write = 1; - s->flags.filtrated = 1; - s->fname = cdk_strdup(file); - if (!s->fname) { - cdk_free(s); - gnutls_assert(); - return CDK_Out_Of_Core; - } - s->fp = fopen(file, "w+b"); - if (!s->fp) { - cdk_free(s->fname); - cdk_free(s); - gnutls_assert(); - return CDK_File_Error; - } -#ifdef DEBUG_STREAM - _gnutls_read_log("stream create fd=%d\n", fileno(s->fp)); -#endif - *ret_s = s; - return 0; -} - - -/** - * cdk_stream_tmp_new: - * @r_out: the new temp stream. - * - * Allocates a new tempory stream which is not associated with a file. - */ -cdk_error_t cdk_stream_tmp_new(cdk_stream_t * r_out) -{ - return cdk_stream_new(NULL, r_out); -} - - - -/** - * cdk_stream_tmp_from_mem: - * @buf: the buffer which shall be written to the temp stream. - * @buflen: how large the buffer is - * @r_out: the new stream with the given contents. - * - * Creates a new tempory stream with the given contests. - */ -cdk_error_t -cdk_stream_tmp_from_mem(const void *buf, size_t buflen, - cdk_stream_t * r_out) -{ - cdk_stream_t s; - cdk_error_t rc; - int nwritten; - - *r_out = NULL; - rc = cdk_stream_tmp_new(&s); - if (rc) { - gnutls_assert(); - return rc; - } - - nwritten = cdk_stream_write(s, buf, buflen); - if (nwritten == EOF) { - cdk_stream_close(s); - gnutls_assert(); - return s->error; - } - cdk_stream_seek(s, 0); - *r_out = s; - return 0; -} - - -cdk_error_t -_cdk_stream_fpopen(FILE * fp, unsigned write_mode, cdk_stream_t * ret_out) -{ - cdk_stream_t s; - - *ret_out = NULL; - s = cdk_calloc(1, sizeof *s); - if (!s) { - gnutls_assert(); - return CDK_Out_Of_Core; - } -#ifdef DEBUG_STREAM - _gnutls_read_log("stream ref fd=%d\n", fileno(fp)); -#endif - s->fp = fp; - s->fp_ref = 1; - s->flags.filtrated = 1; - s->flags.write = write_mode; - - *ret_out = s; - return 0; -} - - -cdk_error_t _cdk_stream_append(const char *file, cdk_stream_t * ret_s) -{ - cdk_stream_t s; - cdk_error_t rc; - - if (!ret_s) { - gnutls_assert(); - return CDK_Inv_Value; - } - *ret_s = NULL; - - rc = _cdk_stream_open_mode(file, "a+b", &s); - if (rc) { - gnutls_assert(); - return rc; - } - - /* In the append mode, we need to write to the flag. */ - s->flags.write = 1; - *ret_s = s; - return 0; -} - -/** - * cdk_stream_is_compressed: - * @s: the stream - * - * Check whether stream is compressed. - * - * Returns: 0 if the stream is uncompressed, otherwise the compression - * algorithm. - */ -int cdk_stream_is_compressed(cdk_stream_t s) -{ - if (!s) - return 0; - return s->flags.compressed; -} - -void _cdk_stream_set_compress_algo(cdk_stream_t s, int algo) -{ - if (!s) - return; - s->flags.compressed = algo; -} - - -cdk_error_t cdk_stream_flush(cdk_stream_t s) -{ - cdk_error_t rc; - - if (!s) { - gnutls_assert(); - return CDK_Inv_Value; - } - - /* The user callback does not support flush */ - if (s->cbs_hd) - return 0; - - /* For read-only streams, no flush is needed. */ - if (!s->flags.write) - return 0; - - if (!s->flags.filtrated) { - if (!cdk_stream_get_length(s)) - return 0; - rc = cdk_stream_seek(s, 0); - if (!rc) - rc = stream_flush(s); - if (!rc) - rc = stream_filter_write(s); - s->flags.filtrated = 1; - if (rc) { - s->error = rc; - gnutls_assert(); - return rc; - } - } - return 0; -} - - -void cdk_stream_tmp_set_mode(cdk_stream_t s, int val) -{ - if (s && s->flags.temp) - s->fmode = val; -} - - -/** - * cdk_stream_close: - * @s: The STREAM object. - * - * Close a stream and flush all buffers. This function work different - * for read or write streams. When the stream is for reading, the - * filtering is already done and we can simply close the file and all - * buffers. But for the case it's a write stream, we need to apply - * all registered filters now. The file is closed in the filter - * function and not here. - **/ -cdk_error_t cdk_stream_close(cdk_stream_t s) -{ - struct stream_filter_s *f, *f2; - cdk_error_t rc; - - if (!s) { - gnutls_assert(); - return CDK_Inv_Value; - } -#ifdef DEBUG_STREAM - _gnutls_read_log("close stream ref=%d `%s'\n", - s->fp_ref, s->fname ? s->fname : "[temp]"); -#endif - - /* In the user callback mode, we call the release cb if possible - and just free the stream. */ - if (s->cbs_hd) { - if (s->cbs.release) - rc = s->cbs.release(s->cbs_hd); - else - rc = 0; - cdk_free(s); - gnutls_assert(); - return rc; - } - - - rc = 0; - if (!s->flags.filtrated && !s->error) - rc = cdk_stream_flush(s); - if (!s->fp_ref && (s->fname || s->flags.temp)) { - int err; - -#ifdef DEBUG_STREAM - _gnutls_read_log("close stream fd=%d\n", fileno(s->fp)); -#endif - err = fclose(s->fp); - s->fp = NULL; - if (err) - rc = CDK_File_Error; - } - - /* Iterate over the filter list and use the cleanup flag to - free the allocated internal structures. */ - f = s->filters; - while (f) { - f2 = f->next; - if (f->fnct) - f->fnct(f->uint8_t, STREAMCTL_FREE, NULL, NULL); - cdk_free(f); - f = f2; - } - - if (s->fname) { - cdk_free(s->fname); - s->fname = NULL; - } - - cdk_free(s->cache.buf); - s->cache.alloced = 0; - - cdk_free(s); - - if (rc) - gnutls_assert(); - - return rc; -} - - -/** - * cdk_stream_eof: - * @s: The STREAM object. - * - * Return if the associated file handle was set to EOF. This - * function will only work with read streams. - **/ -int cdk_stream_eof(cdk_stream_t s) -{ - return s ? s->flags.eof : -1; -} - - -const char *_cdk_stream_get_fname(cdk_stream_t s) -{ - if (!s) - return NULL; - if (s->flags.temp) - return NULL; - return s->fname ? s->fname : NULL; -} - - -/* Return the underlying FP of the stream. - WARNING: This handle should not be closed. */ -FILE *_cdk_stream_get_fp(cdk_stream_t s) -{ - return s ? s->fp : NULL; -} - - -int _cdk_stream_get_errno(cdk_stream_t s) -{ - return s ? s->error : CDK_Inv_Value; -} - - -/** - * cdk_stream_get_length: - * @s: The STREAM object. - * - * Return the length of the associated file handle. This function - * should work for both read and write streams. For write streams an - * additional flush is used to write possible pending data. - **/ -off_t cdk_stream_get_length(cdk_stream_t s) -{ - struct stat statbuf; - cdk_error_t rc; - - if (!s) { - gnutls_assert(); - return (off_t) 0; - } - - /* The user callback does not support stat. */ - if (s->cbs_hd) - return 0; - - rc = stream_flush(s); - if (rc) { - s->error = rc; - gnutls_assert(); - return (off_t) 0; - } - - if (fstat(fileno(s->fp), &statbuf)) { - s->error = CDK_File_Error; - gnutls_assert(); - return (off_t) 0; - } - - return statbuf.st_size; -} - - -static struct stream_filter_s *filter_add2(cdk_stream_t s) -{ - struct stream_filter_s *f; - - assert(s); - - f = cdk_calloc(1, sizeof *f); - if (!f) - return NULL; - f->next = s->filters; - s->filters = f; - return f; -} - - -static struct stream_filter_s *filter_search(cdk_stream_t s, - filter_fnct_t fnc) -{ - struct stream_filter_s *f; - - assert(s); - - for (f = s->filters; f; f = f->next) { - if (f->fnct == fnc) - return f; - } - - return NULL; -} - -static inline void set_uint8_t(struct stream_filter_s *f) -{ - switch (f->type) { - case fARMOR: - f->uint8_t = &f->u.afx; - break; - case fCIPHER: - f->uint8_t = &f->u.cfx; - break; - case fLITERAL: - f->uint8_t = &f->u.pfx; - break; - case fCOMPRESS: - f->uint8_t = &f->u.zfx; - break; - case fHASH: - f->uint8_t = &f->u.mfx; - break; - case fTEXT: - f->uint8_t = &f->u.tfx; - break; - default: - f->uint8_t = NULL; - } - -} - -struct stream_filter_s *filter_add(cdk_stream_t s, filter_fnct_t fnc, - int type) -{ - struct stream_filter_s *f; - - assert(s); - - s->flags.filtrated = 0; - f = filter_search(s, fnc); - if (f) - return f; - f = filter_add2(s); - if (!f) - return NULL; - f->fnct = fnc; - f->flags.enabled = 1; - f->tmp = NULL; - f->type = type; - - set_uint8_t(f); - - return f; -} - -static int stream_get_mode(cdk_stream_t s) -{ - assert(s); - - if (s->flags.temp) - return s->fmode; - return s->flags.write; -} - - -static filter_fnct_t stream_id_to_filter(int type) -{ - switch (type) { - case fARMOR: - return _cdk_filter_armor; - case fLITERAL: - return _cdk_filter_literal; - case fTEXT: - return _cdk_filter_text; -/* case fCIPHER : return _cdk_filter_cipher; */ -/* case fCOMPRESS: return _cdk_filter_compress; */ - default: - return NULL; - } -} - - -/** - * cdk_stream_filter_disable: - * @s: The STREAM object - * @type: The numberic filter ID. - * - * Disables the filter with the type 'type'. - **/ -cdk_error_t cdk_stream_filter_disable(cdk_stream_t s, int type) -{ - struct stream_filter_s *f; - filter_fnct_t fnc; - - if (!s) { - gnutls_assert(); - return CDK_Inv_Value; - } - - fnc = stream_id_to_filter(type); - if (!fnc) { - gnutls_assert(); - return CDK_Inv_Value; - } - f = filter_search(s, fnc); - if (f) - f->flags.enabled = 0; - return 0; -} - - -/* WARNING: tmp should not be closed by the caller. */ -static cdk_error_t stream_fp_replace(cdk_stream_t s, FILE ** tmp) -{ - int rc; - - assert(s); - -#ifdef DEBUG_STREAM - _gnutls_read_log("replace stream fd=%d with fd=%d\n", - fileno(s->fp), fileno(*tmp)); -#endif - rc = fclose(s->fp); - if (rc) { - s->fp = NULL; - gnutls_assert(); - return CDK_File_Error; - } - s->fp = *tmp; - *tmp = NULL; - return 0; -} - - -/* This function is exactly like filter_read, except the fact that we can't - use tmpfile () all the time. That's why we open the real file when there - is no last filter. */ -static cdk_error_t stream_filter_write(cdk_stream_t s) -{ - struct stream_filter_s *f; - cdk_error_t rc = 0; - - assert(s); - - if (s->flags.filtrated) { - gnutls_assert(); - return CDK_Inv_Value; - } - - for (f = s->filters; f; f = f->next) { - if (!f->flags.enabled) - continue; - /* if there is no next filter, create the final output file */ -#ifdef DEBUG_STREAM - _gnutls_read_log - ("filter [write]: last filter=%d fname=%s\n", - f->next ? 1 : 0, s->fname); -#endif - if (!f->next && s->fname) - f->tmp = fopen(s->fname, "w+b"); - else - f->tmp = _cdk_tmpfile(); - if (!f->tmp) { - rc = CDK_File_Error; - break; - } - /* If there is no next filter, flush the cache. We also do this - when the next filter is the armor filter because this filter - is special and before it starts, all data should be written. */ - if ((!f->next || f->next->type == fARMOR) && s->cache.size) { - rc = stream_cache_flush(s, f->tmp); - if (rc) - break; - } - rc = f->fnct(f->uint8_t, f->ctl, s->fp, f->tmp); -#ifdef DEBUG_STREAM - _gnutls_read_log("filter [write]: type=%d rc=%d\n", - f->type, rc); -#endif - if (!rc) - rc = stream_fp_replace(s, &f->tmp); - if (!rc) - rc = cdk_stream_seek(s, 0); - if (rc) { -#ifdef DEBUG_STREAM - _gnutls_read_log("filter [close]: fd=%d\n", - fileno(f->tmp)); -#endif - fclose(f->tmp); - f->tmp = NULL; - break; - } - } - return rc; -} - - -/* Here all data from the file handle is passed through all filters. - The scheme works like this: - Create a tempfile and use it for the output of the filter. Then the - original file handle will be closed and replace with the temp handle. - The file pointer will be set to the begin and the game starts again. */ -static cdk_error_t stream_filter_read(cdk_stream_t s) -{ - struct stream_filter_s *f; - cdk_error_t rc = 0; - - assert(s); - - if (s->flags.filtrated) - return 0; - - for (f = s->filters; f; f = f->next) { - if (!f->flags.enabled) - continue; - if (f->flags.error) { -#ifdef DEBUG_STREAM - _gnutls_read_log - ("filter %s [read]: has the error flag; skipped\n", - s->fname ? s->fname : "[temp]"); -#endif - continue; - } - - f->tmp = _cdk_tmpfile(); - if (!f->tmp) { - rc = CDK_File_Error; - break; - } - rc = f->fnct(f->uint8_t, f->ctl, s->fp, f->tmp); -#ifdef DEBUG_STREAM - _gnutls_read_log("filter %s [read]: type=%d rc=%d\n", - s->fname ? s->fname : "[temp]", f->type, - rc); -#endif - if (rc) { - f->flags.error = 1; - break; - } - - f->flags.error = 0; - /* If the filter is read-only, do not replace the FP because - the contents were not altered in any way. */ - if (!f->flags.rdonly) { - rc = stream_fp_replace(s, &f->tmp); - if (rc) - break; - } else { - fclose(f->tmp); - f->tmp = NULL; - } - rc = cdk_stream_seek(s, 0); - if (rc) - break; - /* Disable the filter after it was successfully used. The idea - is the following: let's say the armor filter was pushed and - later more filters were added. The second time the filter code - will be executed, only the new filter should be started but - not the old because we already used it. */ - f->flags.enabled = 0; - } - - return rc; -} - - -void *_cdk_stream_get_uint8_t(cdk_stream_t s, int fid) -{ - struct stream_filter_s *f; - - if (!s) - return NULL; - - for (f = s->filters; f; f = f->next) { - if ((int) f->type == fid) - return f->uint8_t; - } - return NULL; -} - - -/** - * cdk_stream_read: - * @s: The STREAM object. - * @buf: The buffer to insert the readed bytes. - * @count: Request so much bytes. - * - * Tries to read count bytes from the STREAM object. - * When this function is called the first time, it can take a while - * because all filters need to be processed. Please remember that you - * need to add the filters in reserved order. - **/ -int cdk_stream_read(cdk_stream_t s, void *buf, size_t buflen) -{ - int nread; - int rc; - - if (!s) { - gnutls_assert(); - return EOF; - } - - if (s->cbs_hd) { - if (s->cbs.read) - return s->cbs.read(s->cbs_hd, buf, buflen); - return 0; - } - - if (s->flags.write && !s->flags.temp) { - s->error = CDK_Inv_Mode; - gnutls_assert(); - return EOF; /* This is a write stream */ - } - - if (!s->flags.no_filter && !s->cache.on && !s->flags.filtrated) { - rc = stream_filter_read(s); - if (rc) { - s->error = rc; - if (s->fp && feof(s->fp)) - s->flags.eof = 1; - gnutls_assert(); - return EOF; - } - s->flags.filtrated = 1; - } - - if (!buf || !buflen) - return 0; - - nread = fread(buf, 1, buflen, s->fp); - if (!nread) - nread = EOF; - - if (feof(s->fp)) { - s->error = 0; - s->flags.eof = 1; - } - return nread; -} - - -int cdk_stream_getc(cdk_stream_t s) -{ - unsigned char buf[2] = {0}; - int nread; - - if (!s) { - gnutls_assert(); - return EOF; - } - nread = cdk_stream_read(s, buf, 1); - if (nread == EOF) { - s->error = CDK_File_Error; - gnutls_assert(); - return EOF; - } - return buf[0]; -} - - -/** - * cdk_stream_write: - * @s: The STREAM object - * @buf: The buffer with the values to write. - * @count: The size of the buffer. - * - * Tries to write count bytes into the stream. - * In this function we simply write the bytes to the stream. We can't - * use the filters here because it would mean they have to support - * partial flushing. - **/ -int cdk_stream_write(cdk_stream_t s, const void *buf, size_t count) -{ - int nwritten; - - if (!s) { - gnutls_assert(); - return EOF; - } - - if (s->cbs_hd) { - if (s->cbs.write) - return s->cbs.write(s->cbs_hd, buf, count); - return 0; - } - - if (!s->flags.write) { - s->error = CDK_Inv_Mode; /* this is a read stream */ - gnutls_assert(); - return EOF; - } - - if (!buf || !count) - return stream_flush(s); - - if (s->cache.on) { -#ifdef DEBUG_STREAM - _gnutls_read_log("stream[ref=%u]: written %d bytes\n", - s->fp_ref, (int) count); -#endif - - /* We need to resize the buffer if the additional data wouldn't - fit into it. We allocate more memory to avoid to resize it the - next time the function is used. */ - if (s->cache.size + count > s->cache.alloced) { - byte *old = s->cache.buf; - - s->cache.buf = - cdk_calloc(1, - s->cache.alloced + count + - STREAM_BUFSIZE); - s->cache.alloced += (count + STREAM_BUFSIZE); - memcpy(s->cache.buf, old, s->cache.size); - cdk_free(old); -#ifdef DEBUG_STREAM - _gnutls_read_log - ("stream: enlarge cache to %d octets\n", - (int) s->cache.alloced); -#endif - } - - memcpy(s->cache.buf + s->cache.size, buf, count); - s->cache.size += count; - return count; - } -#ifdef DEBUG_STREAM - _gnutls_read_log("stream[fd=%u]: written %d bytes\n", - fileno(s->fp), (int) count); -#endif - - nwritten = fwrite(buf, 1, count, s->fp); - if (!nwritten) - nwritten = EOF; - return nwritten; -} - - -int cdk_stream_putc(cdk_stream_t s, int c) -{ - byte buf[2]; - int nwritten; - - if (!s) { - gnutls_assert(); - return EOF; - } - buf[0] = c; - nwritten = cdk_stream_write(s, buf, 1); - if (nwritten == EOF) - return EOF; - return 0; -} - - -off_t cdk_stream_tell(cdk_stream_t s) -{ - return s ? ftell(s->fp) : (off_t) 0; -} - - -cdk_error_t cdk_stream_seek(cdk_stream_t s, off_t offset) -{ - off_t len; - - if (!s) { - gnutls_assert(); - return CDK_Inv_Value; - } - - if (s->cbs_hd) { - if (s->cbs.seek) - return s->cbs.seek(s->cbs_hd, offset); - return 0; - } - - /* Set or reset the EOF flag. */ - len = cdk_stream_get_length(s); - if (len == offset) - s->flags.eof = 1; - else - s->flags.eof = 0; - - if (fseek(s->fp, offset, SEEK_SET)) { - gnutls_assert(); - return CDK_File_Error; - } - return 0; -} - - -static cdk_error_t stream_flush(cdk_stream_t s) -{ - assert(s); - - /* For some constellations it cannot be assured that the - return value is defined, thus we ignore it for now. */ - (void) fflush(s->fp); - return 0; -} - - -/** - * cdk_stream_set_armor_flag: - * @s: the stream object - * @type: the type of armor to use - * - * If the file is in read-mode, no armor type needs to be - * defined (armor_type=0) because the armor filter will be - * used for decoding existing armor data. - * For the write mode, @armor_type can be set to any valid - * armor type (message, key, sig). - **/ -cdk_error_t cdk_stream_set_armor_flag(cdk_stream_t s, int armor_type) -{ - struct stream_filter_s *f; - - if (!s) { - gnutls_assert(); - return CDK_Inv_Value; - } - f = filter_add(s, _cdk_filter_armor, fARMOR); - if (!f) { - gnutls_assert(); - return CDK_Out_Of_Core; - } - f->u.afx.idx = f->u.afx.idx2 = armor_type; - f->ctl = stream_get_mode(s); - return 0; -} - - -/** - * cdk_stream_set_literal_flag: - * @s: the stream object - * @mode: the mode to use (binary, text, unicode) - * @fname: the file name to store in the packet. - * - * In read mode it kicks off the literal decoding routine to - * unwrap the data from the packet. The @mode parameter is ignored. - * In write mode the function can be used to wrap the stream data - * into a literal packet with the given mode and file name. - **/ -cdk_error_t -cdk_stream_set_literal_flag(cdk_stream_t s, cdk_lit_format_t mode, - const char *fname) -{ - struct stream_filter_s *f; - const char *orig_fname; - -#ifdef DEBUG_STREAM - _gnutls_read_log("stream: enable literal mode.\n"); -#endif - - if (!s) { - gnutls_assert(); - return CDK_Inv_Value; - } - - orig_fname = _cdk_stream_get_fname(s); - f = filter_add(s, _cdk_filter_literal, fLITERAL); - if (!f) { - gnutls_assert(); - return CDK_Out_Of_Core; - } - f->u.pfx.mode = mode; - f->u.pfx.filename = fname ? cdk_strdup(fname) : NULL; - f->u.pfx.orig_filename = - orig_fname ? cdk_strdup(orig_fname) : NULL; - f->ctl = stream_get_mode(s); - if (s->blkmode > 0) { - f->u.pfx.blkmode.on = 1; - f->u.pfx.blkmode.size = s->blkmode; - } - return 0; -} - - -/** - * cdk_stream_set_compress_flag: - * @s: the stream object - * @algo: the compression algo - * @level: level of compression (0..9) - * - * In read mode it kicks off the decompression filter to retrieve - * the uncompressed data. - * In write mode the stream data will be compressed with the - * given algorithm at the given level. - **/ -cdk_error_t -cdk_stream_set_compress_flag(cdk_stream_t s, int algo, int level) -{ - - gnutls_assert(); - return CDK_Not_Implemented; -} - - -/** - * cdk_stream_set_text_flag: - * @s: the stream object - * @lf: line ending - * - * Pushes the text filter to store the stream data in cannoncial format. - **/ -cdk_error_t cdk_stream_set_text_flag(cdk_stream_t s, const char *lf) -{ - struct stream_filter_s *f; - - if (!s) { - gnutls_assert(); - return CDK_Inv_Value; - } - f = filter_add(s, _cdk_filter_text, fTEXT); - if (!f) { - gnutls_assert(); - return CDK_Out_Of_Core; - } - f->ctl = stream_get_mode(s); - f->u.tfx.lf = lf; - return 0; -} - -/** - * cdk_stream_enable_cache: - * @s: the stream object - * @val: 1=on, 0=off - * - * Enables or disable the cache section of a stream object. - **/ -cdk_error_t cdk_stream_enable_cache(cdk_stream_t s, int val) -{ - if (!s) { - gnutls_assert(); - return CDK_Inv_Value; - } - if (!s->flags.write) { - gnutls_assert(); - return CDK_Inv_Mode; - } - s->cache.on = val; - if (!s->cache.buf) { - s->cache.buf = cdk_calloc(1, STREAM_BUFSIZE); - s->cache.alloced = STREAM_BUFSIZE; -#ifdef DEBUG_STREAM - _gnutls_read_log("stream: allocate cache of %d octets\n", - STREAM_BUFSIZE); -#endif - } - return 0; -} - - -static int stream_cache_flush(cdk_stream_t s, FILE * fp) -{ - int nwritten; - - assert(s); - - /* FIXME: We should find a way to use cdk_stream_write here. */ - if (s->cache.size > 0) { - nwritten = fwrite(s->cache.buf, 1, s->cache.size, fp); - if (!nwritten) { - gnutls_assert(); - return CDK_File_Error; - } - s->cache.size = 0; - s->cache.on = 0; - memset(s->cache.buf, 0, s->cache.alloced); - } - return 0; -} - - -/** - * cdk_stream_kick_off: - * @inp: the input stream - * @out: the output stream. - * - * Passes the entire data from @inp into the output stream @out - * with all the activated filters. - */ -cdk_error_t cdk_stream_kick_off(cdk_stream_t inp, cdk_stream_t out) -{ - byte buf[BUFSIZE]; - int nread, nwritten; - cdk_error_t rc; - - if (!inp || !out) { - gnutls_assert(); - return CDK_Inv_Value; - } - rc = CDK_Success; - while (!cdk_stream_eof(inp)) { - nread = cdk_stream_read(inp, buf, DIM(buf)); - if (!nread || nread == EOF) - break; - nwritten = cdk_stream_write(out, buf, nread); - if (!nwritten || nwritten == EOF) { /* In case of errors, we leave the loop. */ - rc = inp->error; - break; - } - } - - memset(buf, 0, sizeof(buf)); - return rc; -} - - -/** - * cdk_stream_mmap_part: - * @s: the stream - * @off: the offset where to start - * @len: how much bytes shall be mapped - * @ret_buf: the buffer to store the content - * @ret_buflen: length of the buffer - * - * Maps the data of the given stream into a memory section. @ret_count - * contains the length of the buffer. - **/ -cdk_error_t -cdk_stream_mmap_part(cdk_stream_t s, off_t off, size_t len, - byte ** ret_buf, size_t * ret_buflen) -{ - cdk_error_t rc; - off_t oldpos; - unsigned int n; - - if (!ret_buf || !ret_buflen) { - gnutls_assert(); - return CDK_Inv_Value; - } - *ret_buf = NULL; - *ret_buflen = 0; - - if (!s) { - gnutls_assert(); - return CDK_Inv_Value; - } - - /* Memory mapping is not supported on custom I/O objects. */ - if (s->cbs_hd) { -#ifdef DEBUG_STREAM - _gnutls_read_log - ("cdk_stream_mmap_part: not supported on callbacks\n"); -#endif - gnutls_assert(); - return CDK_Inv_Mode; - } - - oldpos = cdk_stream_tell(s); - rc = cdk_stream_flush(s); - if (rc) { - gnutls_assert(); - return rc; - } - rc = cdk_stream_seek(s, off); - if (rc) { - gnutls_assert(); - return rc; - } - if (!len) - len = cdk_stream_get_length(s); - if (!len) { - _gnutls_read_log - ("cdk_stream_mmap_part: invalid file size %lu\n", - (unsigned long) len); - gnutls_assert(); - return s->error; - } - if (len > MAX_MAP_SIZE) { - gnutls_assert(); - return CDK_Too_Short; - } - - *ret_buf = cdk_calloc(1, len + 1); - *ret_buflen = len; - n = cdk_stream_read(s, *ret_buf, len); - if (n != len) - *ret_buflen = n; - rc = cdk_stream_seek(s, oldpos); - if (rc) - gnutls_assert(); - return rc; -} - - -cdk_error_t cdk_stream_mmap(cdk_stream_t inp, byte ** buf, size_t * buflen) -{ - off_t len; - - /* We need to make sure all data is flushed before we retrieve the size. */ - cdk_stream_flush(inp); - len = cdk_stream_get_length(inp); - return cdk_stream_mmap_part(inp, 0, len, buf, buflen); -} - - -/** - * cdk_stream_peek: - * @inp: the input stream handle - * @s: buffer - * @count: number of bytes to peek - * - * The function acts like cdk_stream_read with the difference that - * the file pointer is moved to the old position after the bytes were read. - **/ -int cdk_stream_peek(cdk_stream_t inp, byte * buf, size_t buflen) -{ - off_t off; - int nbytes; - - if (!inp || !buf) - return 0; - if (inp->cbs_hd) - return 0; - - off = cdk_stream_tell(inp); - nbytes = cdk_stream_read(inp, buf, buflen); - if (nbytes == -1) - return 0; - if (cdk_stream_seek(inp, off)) - return 0; - return nbytes; -} - - -/* Try to read a line from the given stream. */ -int _cdk_stream_gets(cdk_stream_t s, char *buf, size_t count) -{ - int c, i; - - assert(s); - - i = 0; - while (!cdk_stream_eof(s) && count > 0) { - c = cdk_stream_getc(s); - if (c == EOF || c == '\r' || c == '\n') { - buf[i++] = '\0'; - break; - } - buf[i++] = c; - count--; - } - return i; -} - - -/* Try to write string into the stream @s. */ -int _cdk_stream_puts(cdk_stream_t s, const char *buf) -{ - return cdk_stream_write(s, buf, strlen(buf)); -} - - -/* Activate the block mode for the given stream. */ -cdk_error_t _cdk_stream_set_blockmode(cdk_stream_t s, size_t nbytes) -{ - assert(s); - -#ifdef DEBUG_STREAM - _gnutls_read_log("stream: activate block mode with blocksize %d\n", - (int) nbytes); -#endif - s->blkmode = nbytes; - return 0; -} - - -/* Return the block mode state of the given stream. */ -int _cdk_stream_get_blockmode(cdk_stream_t s) -{ - return s ? s->blkmode : 0; -} diff --git a/lib/opencdk/stream.h b/lib/opencdk/stream.h deleted file mode 100644 index ec912c505d..0000000000 --- a/lib/opencdk/stream.h +++ /dev/null @@ -1,95 +0,0 @@ -/* stream.h - internal definiton for the STREAM object - * Copyright (C) 2002-2012 Free Software Foundation, Inc. - * - * Author: Timo Schulz - * - * This file is part of OpenCDK. - * - * The OpenCDK 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef CDK_STREAM_H -#define CDK_STREAM_H - -/* The default buffer size for the stream. */ -#define STREAM_BUFSIZE 8192 - -enum { - fDUMMY = 0, - fARMOR = 1, - fCIPHER = 2, - fLITERAL = 3, - fCOMPRESS = 4, - fHASH = 5, - fTEXT = 6 -}; - -/* Type definition for the filter function. */ -typedef int(*filter_fnct_t) (void *uint8_t, int ctl, FILE * in, - FILE * out); - -/* The stream filter context structure. */ -struct stream_filter_s { - struct stream_filter_s *next; - filter_fnct_t fnct; - void *uint8_t; - FILE *tmp; - union { - armor_filter_t afx; - cipher_filter_t cfx; - literal_filter_t pfx; - compress_filter_t zfx; - text_filter_t tfx; - md_filter_t mfx; - } u; - struct { - unsigned enabled:1; - unsigned rdonly:1; - unsigned error:1; - } flags; - unsigned type; - unsigned ctl; -}; - - -/* The stream context structure. */ -struct cdk_stream_s { - struct stream_filter_s *filters; - int fmode; - int error; - size_t blkmode; - struct { - unsigned filtrated:1; - unsigned eof:1; - unsigned write:1; - unsigned temp:1; - unsigned reset:1; - unsigned no_filter:1; - unsigned compressed:3; - } flags; - struct { - unsigned char *buf; - unsigned on:1; - size_t size; - size_t alloced; - } cache; - char *fname; - FILE *fp; - unsigned int fp_ref:1; - struct cdk_stream_cbs_s cbs; - void *cbs_hd; -}; - -#endif /* CDK_STREAM_H */ diff --git a/lib/opencdk/types.h b/lib/opencdk/types.h deleted file mode 100644 index 8fae6ce629..0000000000 --- a/lib/opencdk/types.h +++ /dev/null @@ -1,49 +0,0 @@ -/* types.h - Some type definitions - * Copyright (C) 2002-2012 Free Software Foundation, Inc. - * - * Author: Timo Schulz - * - * This file is part of OpenCDK. - * - * The OpenCDK 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef CDK_TYPES_H -#define CDK_TYPES_H - -#ifndef HAVE_BYTE_TYPEDEF -#undef byte -typedef unsigned char byte; -#define HAVE_BYTE_TYPEDEF -#endif - -#ifndef HAVE_U16_TYPEDEF -#undef u16 -typedef unsigned short u16; -#define HAVE_U16_TYPEDEF -#endif - -#ifndef HAVE_U32_TYPEDEF -#undef u32 -typedef unsigned int u32; -#define HAVE_U32_TYPEDEF -#endif - -#ifndef DIM -#define DIM(v) (sizeof (v)/sizeof ((v)[0])) -#define DIMof(type, member) DIM(((type *)0)->member) -#endif - -#endif /* CDK_TYPES_H */ diff --git a/lib/opencdk/write-packet.c b/lib/opencdk/write-packet.c deleted file mode 100644 index b852e0e8d1..0000000000 --- a/lib/opencdk/write-packet.c +++ /dev/null @@ -1,898 +0,0 @@ -/* write-packet.c - Write OpenPGP packets - * Copyright (C) 2001-2012 Free Software Foundation, Inc. - * - * Author: Timo Schulz - * - * This file is part of OpenCDK. - * - * The OpenCDK 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <string.h> -#include <stdio.h> -#include <assert.h> - -#include "opencdk.h" -#include "main.h" - - -static int stream_write(cdk_stream_t s, const void *buf, size_t buflen) -{ - int nwritten; - - nwritten = cdk_stream_write(s, buf, buflen); - if (nwritten == EOF) - return _cdk_stream_get_errno(s); - return 0; -} - - -static int -stream_read(cdk_stream_t s, void *buf, size_t buflen, size_t * r_nread) -{ - int nread; - - assert(r_nread); - - nread = cdk_stream_read(s, buf, buflen); - if (nread == EOF) - return _cdk_stream_get_errno(s); - *r_nread = nread; - return 0; -} - - -static int stream_putc(cdk_stream_t s, int c) -{ - int nwritten = cdk_stream_putc(s, c); - if (nwritten == EOF) - return _cdk_stream_get_errno(s); - return 0; -} - - -static int write_32(cdk_stream_t out, u32 u) -{ - byte buf[4]; - - buf[0] = u >> 24; - buf[1] = u >> 16; - buf[2] = u >> 8; - buf[3] = u; - return stream_write(out, buf, 4); -} - - -static int write_16(cdk_stream_t out, u16 u) -{ - byte buf[2]; - - buf[0] = u >> 8; - buf[1] = u; - return stream_write(out, buf, 2); -} - - -static size_t calc_mpisize(bigint_t mpi[MAX_CDK_PK_PARTS], size_t ncount) -{ - size_t size, i; - - size = 0; - for (i = 0; i < ncount; i++) - size += (_gnutls_mpi_get_nbits(mpi[i]) + 7) / 8 + 2; - return size; -} - - -static int write_mpi(cdk_stream_t out, bigint_t m) -{ - byte buf[MAX_MPI_BYTES + 2]; - size_t nbits, nread; - int err; - - if (!out || !m) - return CDK_Inv_Value; - nbits = _gnutls_mpi_get_nbits(m); - if (nbits > MAX_MPI_BITS || nbits < 1) - return CDK_MPI_Error; - - nread = MAX_MPI_BYTES + 2; - err = _gnutls_mpi_print_pgp(m, buf, &nread); - if (err < 0) - return map_gnutls_error(err); - return stream_write(out, buf, nread); -} - - -static cdk_error_t -write_mpibuf(cdk_stream_t out, bigint_t mpi[MAX_CDK_PK_PARTS], - size_t count) -{ - size_t i; - cdk_error_t rc; - - for (i = 0; i < count; i++) { - rc = write_mpi(out, mpi[i]); - if (rc) - return rc; - } - return 0; -} - - -static cdk_error_t pkt_encode_len(cdk_stream_t out, size_t pktlen) -{ - cdk_error_t rc; - - if (!out) - return CDK_Inv_Value; - - if (!pktlen) { - /* Block mode, partial bodies, with 'DEF_BLOCKSIZE' from main.h */ - rc = stream_putc(out, (0xE0 | DEF_BLOCKBITS)); - } else if (pktlen < 192) - rc = stream_putc(out, pktlen); - else if (pktlen < 8384) { - pktlen -= 192; - rc = stream_putc(out, (pktlen >> 8) + 192); - if (!rc) - rc = stream_putc(out, (pktlen & 0xff)); - } else { - rc = stream_putc(out, 255); - if (!rc) - rc = write_32(out, pktlen); - } - - return rc; -} - - -static cdk_error_t write_head_new(cdk_stream_t out, size_t size, int type) -{ - cdk_error_t rc; - - if (!out) - return CDK_Inv_Value; - - if (type < 0 || type > 63) - return CDK_Inv_Packet; - rc = stream_putc(out, (0xC0 | type)); - if (!rc) - rc = pkt_encode_len(out, size); - return rc; -} - - -static cdk_error_t write_head_old(cdk_stream_t out, size_t size, int type) -{ - cdk_error_t rc; - int ctb; - - if (!out) - return CDK_Inv_Value; - - if (type < 0 || type > 16) - return CDK_Inv_Packet; - ctb = 0x80 | (type << 2); - if (!size) - ctb |= 3; - else if (size < 256); - else if (size < 65536) - ctb |= 1; - else - ctb |= 2; - rc = stream_putc(out, ctb); - if (!size) - return rc; - if (!rc) { - if (size < 256) - rc = stream_putc(out, size); - else if (size < 65536) - rc = write_16(out, size); - else - rc = write_32(out, size); - } - - return rc; -} - - -/* Write special PGP2 packet header. PGP2 (wrongly) uses two byte header - length for signatures and keys even if the size is < 256. */ -static cdk_error_t pkt_write_head2(cdk_stream_t out, size_t size, int type) -{ - cdk_error_t rc; - - rc = cdk_stream_putc(out, 0x80 | (type << 2) | 1); - if (!rc) - rc = cdk_stream_putc(out, size >> 8); - if (!rc) - rc = cdk_stream_putc(out, size & 0xff); - return rc; -} - - -static int -pkt_write_head(cdk_stream_t out, int old_ctb, size_t size, int type) -{ - if (old_ctb) - return write_head_old(out, size, type); - return write_head_new(out, size, type); -} - - -static int -write_pubkey_enc(cdk_stream_t out, cdk_pkt_pubkey_enc_t pke, int old_ctb) -{ - size_t size; - int rc, nenc; - - if (!out || !pke) - return CDK_Inv_Value; - - if (pke->version < 2 || pke->version > 3) - return CDK_Inv_Packet; - if (!KEY_CAN_ENCRYPT(pke->pubkey_algo)) - return CDK_Inv_Algo; - - if (DEBUG_PKT) - _gnutls_write_log("write_pubkey_enc:\n"); - - nenc = cdk_pk_get_nenc(pke->pubkey_algo); - size = 10 + calc_mpisize(pke->mpi, nenc); - rc = pkt_write_head(out, old_ctb, size, CDK_PKT_PUBKEY_ENC); - if (rc) - return rc; - - rc = stream_putc(out, pke->version); - if (!rc) - rc = write_32(out, pke->keyid[0]); - if (!rc) - rc = write_32(out, pke->keyid[1]); - if (!rc) - rc = stream_putc(out, - _cdk_pub_algo_to_pgp(pke->pubkey_algo)); - if (!rc) - rc = write_mpibuf(out, pke->mpi, nenc); - return rc; -} - - -static cdk_error_t write_mdc(cdk_stream_t out, cdk_pkt_mdc_t mdc) -{ - cdk_error_t rc; - - if (!out || !mdc) - return CDK_Inv_Value; - - if (DEBUG_PKT) - _gnutls_write_log("write_mdc:\n"); - - /* This packet requires a fixed header encoding */ - rc = stream_putc(out, 0xD3); /* packet ID and 1 byte length */ - if (!rc) - rc = stream_putc(out, 0x14); - if (!rc) - rc = stream_write(out, mdc->hash, DIM(mdc->hash)); - return rc; -} - - -static size_t calc_subpktsize(cdk_subpkt_t s) -{ - size_t nbytes; - - /* In the count mode, no buffer is returned. */ - _cdk_subpkt_get_array(s, 1, &nbytes); - return nbytes; -} - - -static cdk_error_t -write_v3_sig(cdk_stream_t out, cdk_pkt_signature_t sig, int nsig) -{ - size_t size; - cdk_error_t rc; - - size = 19 + calc_mpisize(sig->mpi, nsig); - if (is_RSA(sig->pubkey_algo)) - rc = pkt_write_head2(out, size, CDK_PKT_SIGNATURE); - else - rc = pkt_write_head(out, 1, size, CDK_PKT_SIGNATURE); - if (!rc) - rc = stream_putc(out, sig->version); - if (!rc) - rc = stream_putc(out, 5); - if (!rc) - rc = stream_putc(out, sig->sig_class); - if (!rc) - rc = write_32(out, sig->timestamp); - if (!rc) - rc = write_32(out, sig->keyid[0]); - if (!rc) - rc = write_32(out, sig->keyid[1]); - if (!rc) - rc = stream_putc(out, - _cdk_pub_algo_to_pgp(sig->pubkey_algo)); - if (!rc) - rc = stream_putc(out, - _gnutls_hash_algo_to_pgp(sig-> - digest_algo)); - if (!rc) - rc = stream_putc(out, sig->digest_start[0]); - if (!rc) - rc = stream_putc(out, sig->digest_start[1]); - if (!rc) - rc = write_mpibuf(out, sig->mpi, nsig); - return rc; -} - - -static cdk_error_t -write_signature(cdk_stream_t out, cdk_pkt_signature_t sig, int old_ctb) -{ - byte *buf; - size_t nbytes, size, nsig; - cdk_error_t rc; - - if (!out || !sig) - return CDK_Inv_Value; - - if (!KEY_CAN_SIGN(sig->pubkey_algo)) - return gnutls_assert_val(CDK_Inv_Algo); - if (sig->version < 2 || sig->version > 4) - return gnutls_assert_val(CDK_Inv_Packet); - - if (DEBUG_PKT) - _gnutls_write_log("write_signature:\n"); - - nsig = cdk_pk_get_nsig(sig->pubkey_algo); - if (!nsig) - return gnutls_assert_val(CDK_Inv_Algo); - if (sig->version < 4) - return write_v3_sig(out, sig, nsig); - - size = 10 + calc_subpktsize(sig->hashed) - + calc_subpktsize(sig->unhashed) + calc_mpisize(sig->mpi, - nsig); - - rc = pkt_write_head(out, 0, size, CDK_PKT_SIGNATURE); - if (rc) - return gnutls_assert_val(rc); - - rc = stream_putc(out, 4); - if (rc) - return gnutls_assert_val(rc); - - rc = stream_putc(out, sig->sig_class); - if (rc) - return gnutls_assert_val(rc); - - rc = stream_putc(out, _cdk_pub_algo_to_pgp(sig->pubkey_algo)); - if (rc) - return gnutls_assert_val(rc); - - rc = stream_putc(out, _gnutls_hash_algo_to_pgp(sig->digest_algo)); - if (rc) - return gnutls_assert_val(rc); - - rc = write_16(out, sig->hashed_size); - if (rc) - return gnutls_assert_val(rc); - - buf = _cdk_subpkt_get_array(sig->hashed, 0, &nbytes); - if (!buf) - return gnutls_assert_val(CDK_Out_Of_Core); - - rc = stream_write(out, buf, nbytes); - cdk_free(buf); - if (rc) - return gnutls_assert_val(rc); - - rc = write_16(out, sig->unhashed_size); - if (rc) - return gnutls_assert_val(rc); - - buf = _cdk_subpkt_get_array(sig->unhashed, 0, &nbytes); - if (!buf) - return gnutls_assert_val(CDK_Out_Of_Core); - - rc = stream_write(out, buf, nbytes); - cdk_free(buf); - if (rc) - return gnutls_assert_val(rc); - - rc = stream_putc(out, sig->digest_start[0]); - if (rc) - return gnutls_assert_val(rc); - - rc = stream_putc(out, sig->digest_start[1]); - if (rc) - return gnutls_assert_val(rc); - - rc = write_mpibuf(out, sig->mpi, nsig); - if (rc) - return gnutls_assert_val(rc); - - return 0; -} - - -static cdk_error_t -write_public_key(cdk_stream_t out, cdk_pkt_pubkey_t pk, - int is_subkey, int old_ctb) -{ - int pkttype, ndays = 0; - size_t npkey = 0, size = 6; - cdk_error_t rc; - - if (!out || !pk) - return CDK_Inv_Value; - - if (pk->version < 2 || pk->version > 4) - return CDK_Inv_Packet; - - if (DEBUG_PKT) - _gnutls_write_log("write_public_key: subkey=%d\n", - is_subkey); - - pkttype = is_subkey ? CDK_PKT_PUBLIC_SUBKEY : CDK_PKT_PUBLIC_KEY; - npkey = cdk_pk_get_npkey(pk->pubkey_algo); - if (!npkey) - return CDK_Inv_Algo; - if (pk->version < 4) - size += 2; /* expire date */ - if (is_subkey) - old_ctb = 0; - size += calc_mpisize(pk->mpi, npkey); - if (old_ctb) - rc = pkt_write_head2(out, size, pkttype); - else - rc = pkt_write_head(out, old_ctb, size, pkttype); - if (!rc) - rc = stream_putc(out, pk->version); - if (!rc) - rc = write_32(out, pk->timestamp); - if (!rc && pk->version < 4) { - if (pk->expiredate) - ndays = - (u16) ((pk->expiredate - - pk->timestamp) / 86400L); - rc = write_16(out, ndays); - } - if (!rc) - rc = stream_putc(out, - _cdk_pub_algo_to_pgp(pk->pubkey_algo)); - if (!rc) - rc = write_mpibuf(out, pk->mpi, npkey); - return rc; -} - - -static int calc_s2ksize(cdk_pkt_seckey_t sk) -{ - size_t nbytes = 0; - - if (!sk->is_protected) - return 0; - switch (sk->protect.s2k->mode) { - case CDK_S2K_SIMPLE: - nbytes = 2; - break; - case CDK_S2K_SALTED: - nbytes = 10; - break; - case CDK_S2K_ITERSALTED: - nbytes = 11; - break; - case CDK_S2K_GNU_EXT: - nbytes = 2; - break; - } - nbytes += sk->protect.ivlen; - nbytes++; /* single cipher byte */ - return nbytes; -} - - -static cdk_error_t -write_secret_key(cdk_stream_t out, cdk_pkt_seckey_t sk, - int is_subkey, int old_ctb) -{ - cdk_pkt_pubkey_t pk = NULL; - size_t size = 6, npkey, nskey; - int pkttype, s2k_mode; - cdk_error_t rc; - - if (!out || !sk) - return CDK_Inv_Value; - - if (!sk->pk) - return CDK_Inv_Value; - pk = sk->pk; - if (pk->version < 2 || pk->version > 4) - return CDK_Inv_Packet; - - if (DEBUG_PKT) - _gnutls_write_log("write_secret_key:\n"); - - npkey = cdk_pk_get_npkey(pk->pubkey_algo); - nskey = cdk_pk_get_nskey(pk->pubkey_algo); - if (!npkey || !nskey) { - gnutls_assert(); - return CDK_Inv_Algo; - } - if (pk->version < 4) - size += 2; - /* If the key is unprotected, the 1 extra byte: - 1 octet - cipher algorithm byte (0x00) - the other bytes depend on the mode: - a) simple checksum - 2 octets - b) sha-1 checksum - 20 octets */ - size = !sk->is_protected ? size + 1 : size + 1 + calc_s2ksize(sk); - size += calc_mpisize(pk->mpi, npkey); - if (sk->version == 3 || !sk->is_protected) { - if (sk->version == 3) { - size += 2; /* force simple checksum */ - sk->protect.sha1chk = 0; - } else - size += sk->protect.sha1chk ? 20 : 2; - size += calc_mpisize(sk->mpi, nskey); - } else /* We do not know anything about the encrypted mpi's so we - treat the data as uint8_t. */ - size += sk->enclen; - - pkttype = is_subkey ? CDK_PKT_SECRET_SUBKEY : CDK_PKT_SECRET_KEY; - rc = pkt_write_head(out, old_ctb, size, pkttype); - if (!rc) - rc = stream_putc(out, pk->version); - if (!rc) - rc = write_32(out, pk->timestamp); - if (!rc && pk->version < 4) { - u16 ndays = 0; - if (pk->expiredate) - ndays = - (u16) ((pk->expiredate - - pk->timestamp) / 86400L); - rc = write_16(out, ndays); - } - if (!rc) - rc = stream_putc(out, - _cdk_pub_algo_to_pgp(pk->pubkey_algo)); - - if (!rc) - rc = write_mpibuf(out, pk->mpi, npkey); - - if (!rc) { - if (sk->is_protected == 0) - rc = stream_putc(out, 0x00); - else { - if (is_RSA(pk->pubkey_algo) && pk->version < 4) - rc = stream_putc(out, - _gnutls_cipher_to_pgp(sk-> - protect. - algo)); - else if (sk->protect.s2k) { - s2k_mode = sk->protect.s2k->mode; - rc = stream_putc(out, - sk->protect. - sha1chk ? 0xFE : 0xFF); - if (!rc) - rc = stream_putc(out, - _gnutls_cipher_to_pgp - (sk->protect. - algo)); - if (!rc) - rc = stream_putc(out, - sk->protect.s2k-> - mode); - if (!rc) - rc = stream_putc(out, - sk->protect.s2k-> - hash_algo); - if (!rc - && (s2k_mode == 1 || s2k_mode == 3)) { - rc = stream_write(out, - sk->protect.s2k-> - salt, 8); - if (!rc && s2k_mode == 3) - rc = stream_putc(out, - sk-> - protect. - s2k-> - count); - } - } else - return CDK_Inv_Value; - if (!rc) - rc = stream_write(out, sk->protect.iv, - sk->protect.ivlen); - } - } - if (!rc && sk->is_protected && pk->version == 4) { - if (sk->encdata && sk->enclen) - rc = stream_write(out, sk->encdata, sk->enclen); - } else { - if (!rc) - rc = write_mpibuf(out, sk->mpi, nskey); - if (!rc) { - if (!sk->csum) - sk->csum = _cdk_sk_get_csum(sk); - rc = write_16(out, sk->csum); - } - } - - return rc; -} - - -static cdk_error_t -write_compressed(cdk_stream_t out, cdk_pkt_compressed_t cd) -{ - cdk_error_t rc; - - if (!out || !cd) - return CDK_Inv_Value; - - if (DEBUG_PKT) - _gnutls_write_log("packet: write_compressed\n"); - - /* Use an old (RFC1991) header for this packet. */ - rc = pkt_write_head(out, 1, 0, CDK_PKT_COMPRESSED); - if (!rc) - rc = stream_putc(out, cd->algorithm); - return rc; -} - - -static cdk_error_t -write_literal(cdk_stream_t out, cdk_pkt_literal_t pt, int old_ctb) -{ - byte buf[BUFSIZE]; - size_t size; - cdk_error_t rc; - - if (!out || !pt) - return CDK_Inv_Value; - - /* We consider a packet without a body as an invalid packet. - At least one octet must be present. */ - if (!pt->len) - return CDK_Inv_Packet; - - if (DEBUG_PKT) - _gnutls_write_log("write_literal:\n"); - - size = 6 + pt->namelen + pt->len; - rc = pkt_write_head(out, old_ctb, size, CDK_PKT_LITERAL); - if (rc) - return rc; - - rc = stream_putc(out, pt->mode); - if (rc) - return rc; - rc = stream_putc(out, pt->namelen); - if (rc) - return rc; - - if (pt->namelen > 0) - rc = stream_write(out, pt->name, pt->namelen); - if (!rc) - rc = write_32(out, pt->timestamp); - if (rc) - return rc; - - while (!cdk_stream_eof(pt->buf) && !rc) { - rc = stream_read(pt->buf, buf, DIM(buf), &size); - if (!rc) - rc = stream_write(out, buf, size); - } - - memset(buf, 0, sizeof(buf)); - return rc; -} - - -static cdk_error_t -write_onepass_sig(cdk_stream_t out, cdk_pkt_onepass_sig_t sig) -{ - cdk_error_t rc; - - if (!out || !sig) - return CDK_Inv_Value; - - if (sig->version != 3) - return CDK_Inv_Packet; - - if (DEBUG_PKT) - _gnutls_write_log("write_onepass_sig:\n"); - - rc = pkt_write_head(out, 0, 13, CDK_PKT_ONEPASS_SIG); - if (!rc) - rc = stream_putc(out, sig->version); - if (!rc) - rc = stream_putc(out, sig->sig_class); - if (!rc) - rc = stream_putc(out, - _gnutls_hash_algo_to_pgp(sig-> - digest_algo)); - if (!rc) - rc = stream_putc(out, - _cdk_pub_algo_to_pgp(sig->pubkey_algo)); - if (!rc) - rc = write_32(out, sig->keyid[0]); - if (!rc) - rc = write_32(out, sig->keyid[1]); - if (!rc) - rc = stream_putc(out, sig->last); - return rc; -} - - -static cdk_error_t -write_user_id(cdk_stream_t out, cdk_pkt_userid_t id, int old_ctb, - int pkttype) -{ - cdk_error_t rc; - - if (!out || !id) - return CDK_Inv_Value; - - if (pkttype == CDK_PKT_ATTRIBUTE) { - if (!id->attrib_img) - return CDK_Inv_Value; - rc = pkt_write_head(out, old_ctb, id->attrib_len + 6, - CDK_PKT_ATTRIBUTE); - if (rc) - return rc; - /* Write subpacket part. */ - stream_putc(out, 255); - write_32(out, id->attrib_len + 1); - stream_putc(out, 1); - rc = stream_write(out, id->attrib_img, id->attrib_len); - } else { - if (!id->name) - return CDK_Inv_Value; - rc = pkt_write_head(out, old_ctb, id->len, - CDK_PKT_USER_ID); - if (!rc) - rc = stream_write(out, id->name, id->len); - } - - return rc; -} - - -/** - * cdk_pkt_write: - * @out: the output stream handle - * @pkt: the packet itself - * - * Write the contents of @pkt into the @out stream. - * Return 0 on success. - **/ -cdk_error_t cdk_pkt_write(cdk_stream_t out, cdk_packet_t pkt) -{ - cdk_error_t rc; - - if (!out || !pkt) - return CDK_Inv_Value; - - if (DEBUG_PKT) - _gnutls_write_log("write packet pkttype=%d\n", - pkt->pkttype); - - switch (pkt->pkttype) { - case CDK_PKT_LITERAL: - rc = write_literal(out, pkt->pkt.literal, pkt->old_ctb); - break; - case CDK_PKT_ONEPASS_SIG: - rc = write_onepass_sig(out, pkt->pkt.onepass_sig); - break; - case CDK_PKT_MDC: - rc = write_mdc(out, pkt->pkt.mdc); - break; - case CDK_PKT_PUBKEY_ENC: - rc = write_pubkey_enc(out, pkt->pkt.pubkey_enc, - pkt->old_ctb); - break; - case CDK_PKT_SIGNATURE: - rc = write_signature(out, pkt->pkt.signature, - pkt->old_ctb); - break; - case CDK_PKT_PUBLIC_KEY: - rc = write_public_key(out, pkt->pkt.public_key, 0, - pkt->old_ctb); - break; - case CDK_PKT_PUBLIC_SUBKEY: - rc = write_public_key(out, pkt->pkt.public_key, 1, - pkt->old_ctb); - break; - case CDK_PKT_COMPRESSED: - rc = write_compressed(out, pkt->pkt.compressed); - break; - case CDK_PKT_SECRET_KEY: - rc = write_secret_key(out, pkt->pkt.secret_key, 0, - pkt->old_ctb); - break; - case CDK_PKT_SECRET_SUBKEY: - rc = write_secret_key(out, pkt->pkt.secret_key, 1, - pkt->old_ctb); - break; - case CDK_PKT_USER_ID: - case CDK_PKT_ATTRIBUTE: - rc = write_user_id(out, pkt->pkt.user_id, pkt->old_ctb, - pkt->pkttype); - break; - default: - rc = CDK_Inv_Packet; - break; - } - - if (DEBUG_PKT) - _gnutls_write_log("write_packet rc=%d pkttype=%d\n", rc, - pkt->pkttype); - return rc; -} - - -cdk_error_t _cdk_pkt_write2(cdk_stream_t out, int pkttype, void *pktctx) -{ - cdk_packet_t pkt; - cdk_error_t rc; - - rc = cdk_pkt_new(&pkt); - if (rc) - return rc; - - switch (pkttype) { - case CDK_PKT_PUBLIC_KEY: - case CDK_PKT_PUBLIC_SUBKEY: - pkt->pkt.public_key = pktctx; - break; - case CDK_PKT_SIGNATURE: - pkt->pkt.signature = pktctx; - break; - case CDK_PKT_SECRET_KEY: - case CDK_PKT_SECRET_SUBKEY: - pkt->pkt.secret_key = pktctx; - break; - - case CDK_PKT_USER_ID: - pkt->pkt.user_id = pktctx; - break; - } - pkt->pkttype = pkttype; - rc = cdk_pkt_write(out, pkt); - cdk_free(pkt); - return rc; -} - - -cdk_error_t _cdk_pkt_write_fp(FILE * out, cdk_packet_t pkt) -{ - cdk_stream_t so; - cdk_error_t rc; - - rc = _cdk_stream_fpopen(out, 1, &so); - if (rc) - return rc; - rc = cdk_pkt_write(so, pkt); - cdk_stream_close(so); - return rc; -} diff --git a/lib/openpgp/Makefile.am b/lib/openpgp/Makefile.am deleted file mode 100644 index 532bd80a99..0000000000 --- a/lib/openpgp/Makefile.am +++ /dev/null @@ -1,41 +0,0 @@ -## Process this file with automake to produce Makefile.in -# Copyright (C) 2002-2012 Free Software Foundation, Inc. -# -# Author: Nikos Mavrogiannopoulos -# -# This file is part of GnuTLS. -# -# The GnuTLS 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 3 of -# the License, or (at your option) any later version. -# -# The GnuTLS 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 program. If not, see <http://www.gnu.org/licenses/> - -include $(top_srcdir)/lib/common.mk - -AM_CPPFLAGS = \ - -I$(srcdir)/../../gl \ - -I$(builddir)/../../gl \ - -I$(srcdir)/../includes \ - -I$(builddir)/../includes \ - -I$(builddir)/../../gl \ - -I$(srcdir)/.. \ - -I$(srcdir)/../opencdk - -if ENABLE_MINITASN1 -AM_CPPFLAGS += -I$(srcdir)/../minitasn1 -endif - -noinst_LTLIBRARIES = libgnutls_openpgp.la - -COBJECTS = pgp.c pgpverify.c extras.c compat.c privkey.c output.c \ - openpgp.c - -libgnutls_openpgp_la_SOURCES = $(COBJECTS) openpgp_int.h openpgp.h diff --git a/lib/openpgp/compat.c b/lib/openpgp/compat.c deleted file mode 100644 index cf39024c7a..0000000000 --- a/lib/openpgp/compat.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (C) 2002-2012 Free Software Foundation, Inc. - * - * Author: Timo Schulz, Nikos Mavrogiannopoulos - * - * This file is part of GnuTLS. - * - * The GnuTLS 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -/* Compatibility functions on OpenPGP key parsing. - */ - -#include "gnutls_int.h" -#include "errors.h" -#include <openpgp.h> -#include <openpgp_int.h> - -/*- - * gnutls_openpgp_verify_key: - * @hostname: the name of the certificate holder - * @cert_list: the structure that holds the certificates. - * @cert_list_lenght: the items in the cert_list. - * @status: the output of the verification function - * - * Verify all signatures in the certificate list. When the key - * is not available, the signature is skipped. - * - * Returns: a negative error code on error and %GNUTLS_E_SUCCESS (0) on success. - * - * NOTE: this function does not verify using any "web of trust". You - * may use GnuPG for that purpose, or any other external PGP application. - -*/ -int -_gnutls_openpgp_verify_key(const gnutls_certificate_credentials_t cred, - gnutls_x509_subject_alt_name_t type, - const char *hostname, - const gnutls_datum_t * cert_list, - int cert_list_length, - unsigned int verify_flags, - unsigned int *status) -{ - int ret = 0; - gnutls_openpgp_crt_t key = NULL; - unsigned int verify = 0, verify_self = 0; - - if (!cert_list || cert_list_length != 1) { - gnutls_assert(); - return GNUTLS_E_NO_CERTIFICATE_FOUND; - } - - ret = gnutls_openpgp_crt_init(&key); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - ret = - gnutls_openpgp_crt_import(key, &cert_list[0], - GNUTLS_OPENPGP_FMT_RAW); - if (ret < 0) { - gnutls_assert(); - goto leave; - } - - if (cred->keyring != NULL) { - ret = - gnutls_openpgp_crt_verify_ring(key, cred->keyring, 0, - &verify); - if (ret < 0) { - gnutls_assert(); - goto leave; - } - } - - /* Now try the self signature. */ - ret = gnutls_openpgp_crt_verify_self(key, 0, &verify_self); - if (ret < 0) { - gnutls_assert(); - goto leave; - } - - *status = verify_self | verify; - - /* If we only checked the self signature. */ - if (!cred->keyring) - *status |= GNUTLS_CERT_SIGNER_NOT_FOUND; - - if (hostname) { - ret = gnutls_openpgp_crt_check_hostname2(key, hostname, verify_flags); - if (ret == 0) - *status |= GNUTLS_CERT_UNEXPECTED_OWNER; - } - - ret = 0; - - leave: - gnutls_openpgp_crt_deinit(key); - - return ret; -} - -/*- - * gnutls_openpgp_fingerprint: - * @cert: the raw data that contains the OpenPGP public key. - * @fpr: the buffer to save the fingerprint. - * @fprlen: the integer to save the length of the fingerprint. - * - * Returns the fingerprint of the OpenPGP key. Depence on the algorithm, - * the fingerprint can be 16 or 20 bytes. - -*/ -int -_gnutls_openpgp_fingerprint(const gnutls_datum_t * cert, - unsigned char *fpr, size_t * fprlen) -{ - gnutls_openpgp_crt_t key; - int ret; - - ret = gnutls_openpgp_crt_init(&key); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - ret = gnutls_openpgp_crt_import(key, cert, GNUTLS_OPENPGP_FMT_RAW); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - ret = gnutls_openpgp_crt_get_fingerprint(key, fpr, fprlen); - gnutls_openpgp_crt_deinit(key); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - return 0; -} - -/*- - * gnutls_openpgp_get_raw_key_creation_time: - * @cert: the raw data that contains the OpenPGP public key. - * - * Returns the timestamp when the OpenPGP key was created. - -*/ -time_t -_gnutls_openpgp_get_raw_key_creation_time(const gnutls_datum_t * cert) -{ - gnutls_openpgp_crt_t key; - int ret; - time_t tim; - - ret = gnutls_openpgp_crt_init(&key); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - ret = gnutls_openpgp_crt_import(key, cert, GNUTLS_OPENPGP_FMT_RAW); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - tim = gnutls_openpgp_crt_get_creation_time(key); - - gnutls_openpgp_crt_deinit(key); - - return tim; -} - - -/*- - * gnutls_openpgp_get_raw_key_expiration_time: - * @cert: the raw data that contains the OpenPGP public key. - * - * Returns the time when the OpenPGP key expires. A value of '0' means - * that the key doesn't expire at all. - -*/ -time_t -_gnutls_openpgp_get_raw_key_expiration_time(const gnutls_datum_t * cert) -{ - gnutls_openpgp_crt_t key; - int ret; - time_t tim; - - ret = gnutls_openpgp_crt_init(&key); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - ret = gnutls_openpgp_crt_import(key, cert, GNUTLS_OPENPGP_FMT_RAW); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - tim = gnutls_openpgp_crt_get_expiration_time(key); - - gnutls_openpgp_crt_deinit(key); - - return tim; -} diff --git a/lib/openpgp/extras.c b/lib/openpgp/extras.c deleted file mode 100644 index 6bc815d250..0000000000 --- a/lib/openpgp/extras.c +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Copyright (C) 2003-2012 Free Software Foundation, Inc. - * - * Author: Nikos Mavrogiannopoulos, Timo Schulz - * - * This file is part of GnuTLS. - * - * The GnuTLS 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -/* Functions on keyring parsing - */ - -#include "gnutls_int.h" -#include <datum.h> -#include <global.h> -#include "errors.h" -#include <openpgp_int.h> -#include <openpgp.h> -#include <num.h> - -/* Keyring stuff. - */ - -/** - * gnutls_openpgp_keyring_init: - * @keyring: A pointer to the type to be initialized - * - * This function will initialize an keyring structure. - * - * Returns: %GNUTLS_E_SUCCESS on success, or an error code. - **/ -int gnutls_openpgp_keyring_init(gnutls_openpgp_keyring_t * keyring) -{ - *keyring = gnutls_calloc(1, sizeof(gnutls_openpgp_keyring_int)); - - if (*keyring) - return 0; /* success */ - return GNUTLS_E_MEMORY_ERROR; -} - - -/** - * gnutls_openpgp_keyring_deinit: - * @keyring: A pointer to the type to be initialized - * - * This function will deinitialize a keyring structure. - **/ -void gnutls_openpgp_keyring_deinit(gnutls_openpgp_keyring_t keyring) -{ - if (!keyring) - return; - - if (keyring->db) { - cdk_keydb_free(keyring->db); - keyring->db = NULL; - } - - gnutls_free(keyring); -} - -/** - * gnutls_openpgp_keyring_check_id: - * @ring: holds the keyring to check against - * @keyid: will hold the keyid to check for. - * @flags: unused (should be 0) - * - * Check if a given key ID exists in the keyring. - * - * Returns: %GNUTLS_E_SUCCESS on success (if keyid exists) and a - * negative error code on failure. - **/ -int -gnutls_openpgp_keyring_check_id(gnutls_openpgp_keyring_t ring, - const gnutls_openpgp_keyid_t keyid, - unsigned int flags) -{ - cdk_pkt_pubkey_t pk; - uint32_t id[2]; - - id[0] = _gnutls_read_uint32(keyid); - id[1] = _gnutls_read_uint32(&keyid[4]); - - if (!cdk_keydb_get_pk(ring->db, id, &pk)) { - cdk_pk_release(pk); - return 0; - } - - _gnutls_debug_log("PGP: key not found %08lX\n", - (unsigned long) id[1]); - return GNUTLS_E_NO_CERTIFICATE_FOUND; -} - -/** - * gnutls_openpgp_keyring_import: - * @keyring: The structure to store the parsed key. - * @data: The RAW or BASE64 encoded keyring. - * @format: One of #gnutls_openpgp_keyring_fmt elements. - * - * This function will convert the given RAW or Base64 encoded keyring - * to the native #gnutls_openpgp_keyring_t format. The output will be - * stored in 'keyring'. - * - * Returns: %GNUTLS_E_SUCCESS on success, or an error code. - **/ -int -gnutls_openpgp_keyring_import(gnutls_openpgp_keyring_t keyring, - const gnutls_datum_t * data, - gnutls_openpgp_crt_fmt_t format) -{ - cdk_error_t err; - cdk_stream_t input = NULL; - size_t raw_len = 0; - uint8_t *raw_data = NULL; - unsigned free_data = 0; - - if (data->data == NULL || data->size == 0) { - gnutls_assert(); - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - } - - _gnutls_debug_log("PGP: keyring import format '%s'\n", - format == - GNUTLS_OPENPGP_FMT_RAW ? "raw" : "base64"); - - /* Create a new stream from the given data, decode it, and import - * the raw database. This to avoid using opencdk streams which are - * not thread safe. - */ - if (format == GNUTLS_OPENPGP_FMT_BASE64) { - size_t seen = 0; - - err = - cdk_stream_tmp_from_mem(data->data, data->size, - &input); - if (err == 0) - err = cdk_stream_set_armor_flag(input, 0); - if (err) { - gnutls_assert(); - err = _gnutls_map_cdk_rc(err); - goto error; - } - - raw_len = cdk_stream_get_length(input); - if (raw_len == 0) { - gnutls_assert(); - err = GNUTLS_E_BASE64_DECODING_ERROR; - goto error; - } - - raw_data = gnutls_malloc(raw_len); - if (raw_data == NULL) { - gnutls_assert(); - err = GNUTLS_E_MEMORY_ERROR; - goto error; - } - - do { - err = - cdk_stream_read(input, raw_data + seen, - raw_len - seen); - - if (err > 0) - seen += err; - } - while (seen < raw_len && err != EOF && err > 0); - - raw_len = seen; - if (raw_len == 0) { - gnutls_assert(); - err = GNUTLS_E_BASE64_DECODING_ERROR; - goto error; - } - - free_data = 1; - } else { /* RAW */ - raw_len = data->size; - raw_data = data->data; - } - - err = - cdk_keydb_new_from_mem(&keyring->db, 0, 0, raw_data, raw_len); - if (err) - gnutls_assert(); - - if (free_data) { - err = _gnutls_map_cdk_rc(err); - goto error; - } - - return _gnutls_map_cdk_rc(err); - - error: - gnutls_free(raw_data); - cdk_stream_close(input); - - return err; -} - -#define knode_is_pkey(node) \ - cdk_kbnode_find_packet (node, CDK_PKT_PUBLIC_KEY)!=NULL - -/** - * gnutls_openpgp_keyring_get_crt_count: - * @ring: is an OpenPGP key ring - * - * This function will return the number of OpenPGP certificates - * present in the given keyring. - * - * Returns: the number of subkeys, or a negative error code on error. - **/ -int gnutls_openpgp_keyring_get_crt_count(gnutls_openpgp_keyring_t ring) -{ - cdk_kbnode_t knode; - cdk_error_t err; - cdk_keydb_search_t st; - int ret = 0; - - err = - cdk_keydb_search_start(&st, ring->db, CDK_DBSEARCH_NEXT, NULL); - if (err != CDK_Success) { - gnutls_assert(); - return _gnutls_map_cdk_rc(err); - } - - do { - err = cdk_keydb_search(st, ring->db, &knode); - if (err != CDK_Error_No_Key && err != CDK_Success) { - gnutls_assert(); - cdk_keydb_search_release(st); - return _gnutls_map_cdk_rc(err); - } - - if (knode_is_pkey(knode)) - ret++; - - cdk_kbnode_release(knode); - - } - while (err != CDK_Error_No_Key); - - cdk_keydb_search_release(st); - return ret; -} - -/** - * gnutls_openpgp_keyring_get_crt: - * @ring: Holds the keyring. - * @idx: the index of the certificate to export - * @cert: An uninitialized #gnutls_openpgp_crt_t type - * - * This function will extract an OpenPGP certificate from the given - * keyring. If the index given is out of range - * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned. The - * returned structure needs to be deinited. - * - * Returns: %GNUTLS_E_SUCCESS on success, or an error code. - **/ -int -gnutls_openpgp_keyring_get_crt(gnutls_openpgp_keyring_t ring, - unsigned int idx, - gnutls_openpgp_crt_t * cert) -{ - cdk_kbnode_t knode; - cdk_error_t err; - int ret = 0; - unsigned int count = 0; - cdk_keydb_search_t st; - - err = - cdk_keydb_search_start(&st, ring->db, CDK_DBSEARCH_NEXT, NULL); - if (err != CDK_Success) { - gnutls_assert(); - return _gnutls_map_cdk_rc(err); - } - - do { - err = cdk_keydb_search(st, ring->db, &knode); - if (err != CDK_EOF && err != CDK_Success) { - gnutls_assert(); - cdk_keydb_search_release(st); - return _gnutls_map_cdk_rc(err); - } - - if (idx == count && err == CDK_Success) { - ret = gnutls_openpgp_crt_init(cert); - if (ret == 0) - (*cert)->knode = knode; - cdk_keydb_search_release(st); - return ret; - } - - if (knode_is_pkey(knode)) - count++; - - cdk_kbnode_release(knode); - - } - while (err != CDK_EOF); - - cdk_keydb_search_release(st); - return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; -} diff --git a/lib/openpgp/openpgp.c b/lib/openpgp/openpgp.c deleted file mode 100644 index fbec7448b5..0000000000 --- a/lib/openpgp/openpgp.c +++ /dev/null @@ -1,767 +0,0 @@ -/* - * Copyright (C) 2002-2012 Free Software Foundation, Inc. - * - * Author: Timo Schulz, Nikos Mavrogiannopoulos - * - * This file is part of GnuTLS. - * - * The GnuTLS 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -#include "gnutls_int.h" -#include "errors.h" -#include "mpi.h" -#include "num.h" -#include "datum.h" -#include "global.h" -#include "openpgp.h" -#include "read-file.h" -#include <gnutls/abstract.h> -#include <str.h> -#include <tls-sig.h> -#include <stdio.h> -#include <sys/stat.h> - -/* Map an OpenCDK error type to a GnuTLS error type. */ -int _gnutls_map_cdk_rc(int rc) -{ - switch (rc) { - case CDK_Success: - return 0; - case CDK_EOF: - return GNUTLS_E_PARSING_ERROR; - case CDK_Too_Short: - return GNUTLS_E_SHORT_MEMORY_BUFFER; - case CDK_General_Error: - return GNUTLS_E_INTERNAL_ERROR; - case CDK_File_Error: - return GNUTLS_E_FILE_ERROR; - case CDK_MPI_Error: - return GNUTLS_E_MPI_SCAN_FAILED; - case CDK_Error_No_Key: - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - case CDK_Armor_Error: - return GNUTLS_E_BASE64_DECODING_ERROR; - case CDK_Inv_Value: - return GNUTLS_E_INVALID_REQUEST; - default: - return GNUTLS_E_INTERNAL_ERROR; - } -} - -/** - * gnutls_certificate_set_openpgp_key: - * @res: is a #gnutls_certificate_credentials_t type. - * @crt: contains an openpgp public key - * @pkey: is an openpgp private key - * - * This function sets a certificate/private key pair in the - * gnutls_certificate_credentials_t type. This function may be - * called more than once (in case multiple keys/certificates exist - * for the server). - * - * Note that this function requires that the preferred key ids have - * been set and be used. See gnutls_openpgp_crt_set_preferred_key_id(). - * Otherwise the master key will be used. - * - * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, - * otherwise a negative error code is returned. - **/ -int -gnutls_certificate_set_openpgp_key(gnutls_certificate_credentials_t res, - gnutls_openpgp_crt_t crt, - gnutls_openpgp_privkey_t pkey) -{ - int ret, ret2, i; - gnutls_privkey_t privkey; - gnutls_pcert_st *ccert = NULL; - char name[MAX_CN]; - size_t max_size; - gnutls_str_array_t names; - - _gnutls_str_array_init(&names); - - /* this should be first */ - - ret = gnutls_privkey_init(&privkey); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - ret = - gnutls_privkey_import_openpgp(privkey, pkey, - GNUTLS_PRIVKEY_IMPORT_COPY); - if (ret < 0) { - gnutls_assert(); - goto cleanup; - } - - ccert = gnutls_calloc(1, sizeof(gnutls_pcert_st)); - if (ccert == NULL) { - gnutls_assert(); - ret = GNUTLS_E_MEMORY_ERROR; - goto cleanup; - } - - max_size = sizeof(name); - ret = 0; - for (i = 0; !(ret < 0); i++) { - ret = gnutls_openpgp_crt_get_name(crt, i, name, &max_size); - if (ret >= 0) { - ret2 = - _gnutls_str_array_append(&names, name, - max_size); - if (ret2 < 0) { - gnutls_assert(); - ret = ret2; - goto cleanup; - } - } - } - - ret = gnutls_pcert_import_openpgp(ccert, crt, 0); - if (ret < 0) { - gnutls_assert(); - goto cleanup; - } - - ret = certificate_credentials_append_pkey(res, privkey); - if (ret >= 0) - ret = - certificate_credential_append_crt_list(res, names, - ccert, 1); - - if (ret < 0) { - gnutls_assert(); - goto cleanup; - } - - res->ncerts++; - - ret = _gnutls_check_key_cert_match(res); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - return 0; - - cleanup: - gnutls_privkey_deinit(privkey); - gnutls_free(ccert); - _gnutls_str_array_clear(&names); - return ret; -} - -/** - * gnutls_certificate_get_openpgp_key: - * @res: is a #gnutls_certificate_credentials_t type. - * @index: The index of the key to obtain. - * @key: Location to store the key. - * - * Obtains a OpenPGP private key that has been stored in @res with one of - * gnutls_certificate_set_openpgp_key(), - * gnutls_certificate_set_openpgp_key_file(), - * gnutls_certificate_set_openpgp_key_file2(), - * gnutls_certificate_set_openpgp_key_mem(), or - * gnutls_certificate_set_openpgp_key_mem2(). - * The returned key must be deallocated with gnutls_openpgp_privkey_deinit() - * when no longer needed. - * - * If there is no key with the given index, - * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned. If the key with the - * given index is not a X.509 key, %GNUTLS_E_INVALID_REQUEST is returned. - * - * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code. - * - * Since: 3.4.0 - */ -int -gnutls_certificate_get_openpgp_key(gnutls_certificate_credentials_t res, - unsigned index, - gnutls_openpgp_privkey_t *key) -{ - if (index >= res->ncerts) { - gnutls_assert(); - return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; - } - - return gnutls_privkey_export_openpgp(res->pkey[index], key); -} - -/** - * gnutls_certificate_get_openpgp_crt: - * @res: is a #gnutls_certificate_credentials_t type. - * @index: The index of the certificate list to obtain. - * @crt_list: Where to store the certificate list. - * @crt_list_size: Will hold the number of certificates. - * - * Obtains a X.509 certificate list that has been stored in @res with one of - * gnutls_certificate_set_openpgp_key(), - * gnutls_certificate_set_openpgp_key_file(), - * gnutls_certificate_set_openpgp_key_file2(), - * gnutls_certificate_set_openpgp_key_mem(), or - * gnutls_certificate_set_openpgp_key_mem2(). Each certificate in the - * returned certificate list must be deallocated with - * gnutls_openpgp_crt_deinit(), and the list itself must be freed with - * gnutls_free(). - * - * If there is no certificate with the given index, - * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned. If the certificate - * with the given index is not a X.509 certificate, %GNUTLS_E_INVALID_REQUEST - * is returned. - * - * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code. - * - * Since: 3.4.0 - */ -int -gnutls_certificate_get_openpgp_crt(gnutls_certificate_credentials_t res, - unsigned index, - gnutls_openpgp_crt_t **crt_list, - unsigned *crt_list_size) -{ - int ret; - unsigned i; - - if (index >= res->ncerts) { - gnutls_assert(); - return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; - } - - *crt_list_size = res->certs[index].cert_list_length; - *crt_list = gnutls_malloc( - res->certs[index].cert_list_length * sizeof (gnutls_openpgp_crt_t)); - if (*crt_list == NULL) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - for (i = 0; i < res->certs[index].cert_list_length; ++i) { - ret = gnutls_pcert_export_openpgp(&res->certs[index].cert_list[i], crt_list[i]); - if (ret < 0) { - while (i--) - gnutls_openpgp_crt_deinit(*crt_list[i]); - gnutls_free(*crt_list); - *crt_list = NULL; - - return gnutls_assert_val(ret); - } - } - - return 0; -} - -/*- - * gnutls_openpgp_get_key: - * @key: the destination context to save the key. - * @keyring: the datum struct that contains all keyring information. - * @attr: The attribute (keyid, fingerprint, ...). - * @by: What attribute is used. - * - * This function can be used to retrieve keys by different pattern - * from a binary or a file keyring. - -*/ -int -gnutls_openpgp_get_key(gnutls_datum_t * key, - gnutls_openpgp_keyring_t keyring, key_attr_t by, - uint8_t * pattern) -{ - cdk_kbnode_t knode = NULL; - unsigned long keyid[2]; - unsigned char *buf; - void *desc; - size_t len; - int rc = 0; - cdk_keydb_search_t st; - - if (!key || !keyring || by == KEY_ATTR_NONE) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - memset(key, 0, sizeof *key); - - if (by == KEY_ATTR_SHORT_KEYID) { - keyid[0] = _gnutls_read_uint32(pattern); - desc = keyid; - } else if (by == KEY_ATTR_KEYID) { - keyid[0] = _gnutls_read_uint32(pattern); - keyid[1] = _gnutls_read_uint32(pattern + 4); - desc = keyid; - } else - desc = pattern; - rc = cdk_keydb_search_start(&st, keyring->db, by, desc); - if (!rc) - rc = cdk_keydb_search(st, keyring->db, &knode); - - cdk_keydb_search_release(st); - - if (rc) { - rc = _gnutls_map_cdk_rc(rc); - goto leave; - } - - if (!cdk_kbnode_find(knode, CDK_PKT_PUBLIC_KEY)) { - rc = GNUTLS_E_OPENPGP_GETKEY_FAILED; - goto leave; - } - - /* We let the function allocate the buffer to avoid - to call the function twice. */ - rc = cdk_kbnode_write_to_mem_alloc(knode, &buf, &len); - if (!rc) - _gnutls_datum_append(key, buf, len); - gnutls_free(buf); - - leave: - cdk_kbnode_release(knode); - return rc; -} - -/** - * gnutls_certificate_set_openpgp_key_mem: - * @res: the destination context to save the data. - * @cert: the datum that contains the public key. - * @key: the datum that contains the secret key. - * @format: the format of the keys - * - * This function is used to load OpenPGP keys into the GnuTLS credential - * structure. The datum should contain at least one valid non encrypted subkey. - * - * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a - * negative error value. - **/ -int -gnutls_certificate_set_openpgp_key_mem(gnutls_certificate_credentials_t - res, const gnutls_datum_t * cert, - const gnutls_datum_t * key, - gnutls_openpgp_crt_fmt_t format) -{ - return gnutls_certificate_set_openpgp_key_mem2(res, cert, key, - NULL, format); -} - -/** - * gnutls_certificate_set_openpgp_key_file: - * @res: the destination context to save the data. - * @certfile: the file that contains the public key. - * @keyfile: the file that contains the secret key. - * @format: the format of the keys - * - * This function is used to load OpenPGP keys into the GnuTLS - * credentials structure. The file should contain at least one valid non encrypted subkey. - * - * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a - * negative error value. - **/ -int -gnutls_certificate_set_openpgp_key_file(gnutls_certificate_credentials_t - res, const char *certfile, - const char *keyfile, - gnutls_openpgp_crt_fmt_t format) -{ - return gnutls_certificate_set_openpgp_key_file2(res, certfile, - keyfile, NULL, - format); -} - -static int get_keyid(gnutls_openpgp_keyid_t keyid, const char *str) -{ - size_t keyid_size = GNUTLS_OPENPGP_KEYID_SIZE; - size_t len = strlen(str); - gnutls_datum_t tmp; - int ret; - - if (len != 16) { - _gnutls_debug_log - ("The OpenPGP subkey ID has to be 16 hexadecimal characters.\n"); - return GNUTLS_E_INVALID_REQUEST; - } - - tmp.data = (void*)str; - tmp.size = len; - ret = gnutls_hex_decode(&tmp, keyid, &keyid_size); - if (ret < 0) { - _gnutls_debug_log("Error converting hex string: %s.\n", - str); - return GNUTLS_E_INVALID_REQUEST; - } - - return 0; -} - -/** - * gnutls_certificate_set_openpgp_key_mem2: - * @res: the destination context to save the data. - * @cert: the datum that contains the public key. - * @key: the datum that contains the secret key. - * @subkey_id: a hex encoded subkey id - * @format: the format of the keys - * - * This function is used to load OpenPGP keys into the GnuTLS - * credentials structure. The datum should contain at least one valid non encrypted subkey. - * - * The special keyword "auto" is also accepted as @subkey_id. In that - * case the gnutls_openpgp_crt_get_auth_subkey() will be used to - * retrieve the subkey. - * - * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a - * negative error value. - * - * Since: 2.4.0 - **/ -int -gnutls_certificate_set_openpgp_key_mem2(gnutls_certificate_credentials_t - res, const gnutls_datum_t * cert, - const gnutls_datum_t * key, - const char *subkey_id, - gnutls_openpgp_crt_fmt_t format) -{ - gnutls_openpgp_privkey_t pkey; - gnutls_openpgp_crt_t crt; - int ret; - uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; - - ret = gnutls_openpgp_privkey_init(&pkey); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - ret = gnutls_openpgp_privkey_import(pkey, key, format, NULL, 0); - if (ret < 0) { - gnutls_assert(); - gnutls_openpgp_privkey_deinit(pkey); - return ret; - } - - ret = gnutls_openpgp_crt_init(&crt); - if (ret < 0) { - gnutls_assert(); - gnutls_openpgp_privkey_deinit(pkey); - return ret; - } - - ret = gnutls_openpgp_crt_import(crt, cert, format); - if (ret < 0) { - gnutls_assert(); - gnutls_openpgp_privkey_deinit(pkey); - gnutls_openpgp_crt_deinit(crt); - return ret; - } - - if (subkey_id != NULL) { - if (strcasecmp(subkey_id, "auto") == 0) - ret = - gnutls_openpgp_crt_get_auth_subkey(crt, keyid, - 1); - else - ret = get_keyid(keyid, subkey_id); - - if (ret < 0) - gnutls_assert(); - - if (ret >= 0) { - ret = - gnutls_openpgp_crt_set_preferred_key_id(crt, - keyid); - if (ret >= 0) - ret = - gnutls_openpgp_privkey_set_preferred_key_id - (pkey, keyid); - } - - if (ret < 0) { - gnutls_assert(); - gnutls_openpgp_privkey_deinit(pkey); - gnutls_openpgp_crt_deinit(crt); - return ret; - } - } - - ret = gnutls_certificate_set_openpgp_key(res, crt, pkey); - - gnutls_openpgp_crt_deinit(crt); - gnutls_openpgp_privkey_deinit(pkey); - - return ret; -} - -/** - * gnutls_certificate_set_openpgp_key_file2: - * @res: the destination context to save the data. - * @certfile: the file that contains the public key. - * @keyfile: the file that contains the secret key. - * @subkey_id: a hex encoded subkey id - * @format: the format of the keys - * - * This function is used to load OpenPGP keys into the GnuTLS credential - * structure. The file should contain at least one valid non encrypted subkey. - * - * The special keyword "auto" is also accepted as @subkey_id. In that - * case the gnutls_openpgp_crt_get_auth_subkey() will be used to - * retrieve the subkey. - * - * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a - * negative error value. - * - * Since: 2.4.0 - **/ -int -gnutls_certificate_set_openpgp_key_file2(gnutls_certificate_credentials_t - res, const char *certfile, - const char *keyfile, - const char *subkey_id, - gnutls_openpgp_crt_fmt_t format) -{ - struct stat statbuf; - gnutls_datum_t key, cert; - int rc; - size_t size; - - if (!res || !keyfile || !certfile) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - if (stat(certfile, &statbuf) || stat(keyfile, &statbuf)) { - gnutls_assert(); - return GNUTLS_E_FILE_ERROR; - } - - cert.data = (void *) read_binary_file(certfile, &size); - cert.size = (unsigned int) size; - if (cert.data == NULL) { - gnutls_assert(); - return GNUTLS_E_FILE_ERROR; - } - - key.data = (void *) read_binary_file(keyfile, &size); - key.size = (unsigned int) size; - if (key.data == NULL) { - gnutls_assert(); - free(cert.data); - return GNUTLS_E_FILE_ERROR; - } - - rc = gnutls_certificate_set_openpgp_key_mem2(res, &cert, &key, - subkey_id, format); - - free(cert.data); - free(key.data); - - if (rc < 0) { - gnutls_assert(); - return rc; - } - - return 0; -} - - -int gnutls_openpgp_count_key_names(const gnutls_datum_t * cert) -{ - cdk_kbnode_t knode, p, ctx; - cdk_packet_t pkt; - int nuids; - - if (cert == NULL) { - gnutls_assert(); - return 0; - } - - if (cdk_kbnode_read_from_mem(&knode, 0, cert->data, cert->size, 1)) { - gnutls_assert(); - return 0; - } - - ctx = NULL; - for (nuids = 0;;) { - p = cdk_kbnode_walk(knode, &ctx, 0); - if (!p) - break; - pkt = cdk_kbnode_get_packet(p); - if (pkt->pkttype == CDK_PKT_USER_ID) - nuids++; - } - - cdk_kbnode_release(knode); - return nuids; -} - -/** - * gnutls_certificate_set_openpgp_keyring_file: - * @c: A certificate credentials structure - * @file: filename of the keyring. - * @format: format of keyring. - * - * The function is used to set keyrings that will be used internally - * by various OpenPGP functions. For example to find a key when it - * is needed for an operations. The keyring will also be used at the - * verification functions. - * - * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a - * negative error value. - **/ -int -gnutls_certificate_set_openpgp_keyring_file -(gnutls_certificate_credentials_t c, const char *file, - gnutls_openpgp_crt_fmt_t format) -{ - gnutls_datum_t ring; - size_t size; - int rc; - - if (!c || !file) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - ring.data = (void *) read_binary_file(file, &size); - ring.size = (unsigned int) size; - if (ring.data == NULL) { - gnutls_assert(); - return GNUTLS_E_FILE_ERROR; - } - - rc = gnutls_certificate_set_openpgp_keyring_mem(c, ring.data, - ring.size, format); - - free(ring.data); - - return rc; -} - -/** - * gnutls_certificate_set_openpgp_keyring_mem: - * @c: A certificate credentials structure - * @data: buffer with keyring data. - * @dlen: length of data buffer. - * @format: the format of the keyring - * - * The function is used to set keyrings that will be used internally - * by various OpenPGP functions. For example to find a key when it - * is needed for an operations. The keyring will also be used at the - * verification functions. - * - * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a - * negative error value. - **/ -int -gnutls_certificate_set_openpgp_keyring_mem(gnutls_certificate_credentials_t - c, const uint8_t * data, - size_t dlen, - gnutls_openpgp_crt_fmt_t format) -{ - gnutls_datum_t ddata; - int rc; - - ddata.data = (void *) data; - ddata.size = dlen; - - if (!c || !data || !dlen) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - rc = gnutls_openpgp_keyring_init(&c->keyring); - if (rc < 0) { - gnutls_assert(); - return rc; - } - - rc = gnutls_openpgp_keyring_import(c->keyring, &ddata, format); - if (rc < 0) { - gnutls_assert(); - gnutls_openpgp_keyring_deinit(c->keyring); - return rc; - } - - return 0; -} - -/*- - * _gnutls_openpgp_request_key - Receives a key from a database, key server etc - * @ret - a pointer to gnutls_datum_t type. - * @cred - a gnutls_certificate_credentials_t type. - * @key_fingerprint - The keyFingerprint - * @key_fingerprint_size - the size of the fingerprint - * - * Retrieves a key from a local database, keyring, or a key server. The - * return value is locally allocated. - * - -*/ -int -_gnutls_openpgp_request_key(gnutls_session_t session, gnutls_datum_t * ret, - const gnutls_certificate_credentials_t cred, - uint8_t * key_fpr, int key_fpr_size) -{ - int rc = 0; - - if (!ret || !cred || !key_fpr) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - if (key_fpr_size != 16 && key_fpr_size != 20) - return GNUTLS_E_HASH_FAILED; /* only MD5 and SHA1 are supported */ - - rc = gnutls_openpgp_get_key(ret, cred->keyring, KEY_ATTR_FPR, - key_fpr); - - if (rc >= 0) { /* key was found */ - rc = 0; - goto error; - } else - rc = GNUTLS_E_OPENPGP_GETKEY_FAILED; - - /* If the callback function was set, then try this one. */ - if (session->internals.openpgp_recv_key_func != NULL) { - rc = session->internals.openpgp_recv_key_func(session, - key_fpr, - key_fpr_size, - ret); - if (rc < 0) { - gnutls_assert(); - rc = GNUTLS_E_OPENPGP_GETKEY_FAILED; - goto error; - } - } - - error: - - return rc; -} - -/** - * gnutls_openpgp_set_recv_key_function: - * @session: a TLS session - * @func: the callback - * - * This function will set a key retrieval function for OpenPGP keys. This - * callback is only useful in server side, and will be used if the peer - * sent a key fingerprint instead of a full key. - * - * The retrieved key must be allocated using gnutls_malloc(). - * - **/ -void -gnutls_openpgp_set_recv_key_function(gnutls_session_t session, - gnutls_openpgp_recv_key_func func) -{ - session->internals.openpgp_recv_key_func = func; -} diff --git a/lib/openpgp/openpgp.h b/lib/openpgp/openpgp.h deleted file mode 100644 index 3d37bdc314..0000000000 --- a/lib/openpgp/openpgp.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2002-2012 Free Software Foundation, Inc. - * - * Author: Timo Schulz, Nikos Mavrogiannopoulos - * - * This file is part of GnuTLS. - * - * The GnuTLS 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -#include <config.h> - -#ifdef ENABLE_OPENPGP - -#ifndef GNUTLS_OPENPGP_LOCAL_H -#define GNUTLS_OPENPGP_LOCAL_H - -#include <auth/cert.h> -#include <opencdk.h> -#include <gnutls/abstract.h> - -/* OpenCDK compatible */ -typedef enum { - KEY_ATTR_NONE = 0, - KEY_ATTR_SHORT_KEYID = 3, - KEY_ATTR_KEYID = 4, - KEY_ATTR_FPR = 5 -} key_attr_t; - -int gnutls_openpgp_count_key_names(const gnutls_datum_t * cert); - -int gnutls_openpgp_get_key(gnutls_datum_t * key, - gnutls_openpgp_keyring_t keyring, - key_attr_t by, uint8_t * pattern); - -/* internal */ -int -_gnutls_openpgp_privkey_cpy(gnutls_openpgp_privkey_t dest, - gnutls_openpgp_privkey_t src); - -int -_gnutls_openpgp_request_key(gnutls_session_t, - gnutls_datum_t * ret, - const gnutls_certificate_credentials_t cred, - uint8_t * key_fpr, int key_fpr_size); - -int -_gnutls_openpgp_verify_key(const gnutls_certificate_credentials_t cred, - gnutls_x509_subject_alt_name_t type, - const char *hostname, - const gnutls_datum_t * cert_list, - int cert_list_length, - unsigned int verify_flags, - unsigned int *status); -int _gnutls_openpgp_fingerprint(const gnutls_datum_t * cert, - unsigned char *fpr, size_t * fprlen); -time_t _gnutls_openpgp_get_raw_key_creation_time(const gnutls_datum_t * - cert); -time_t _gnutls_openpgp_get_raw_key_expiration_time(const gnutls_datum_t * - cert); - -int -_gnutls_openpgp_privkey_sign_hash(gnutls_openpgp_privkey_t key, - const gnutls_datum_t * hash, - gnutls_datum_t * signature); - - -int -_gnutls_openpgp_privkey_decrypt_data(gnutls_openpgp_privkey_t key, - unsigned int flags, - const gnutls_datum_t * ciphertext, - gnutls_datum_t * plaintext); - -#endif /*GNUTLS_OPENPGP_LOCAL_H */ - -#endif /*ENABLE_OPENPGP */ diff --git a/lib/openpgp/openpgp_int.h b/lib/openpgp/openpgp_int.h deleted file mode 100644 index fa55e3e28f..0000000000 --- a/lib/openpgp/openpgp_int.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2002-2012 Free Software Foundation, Inc. - * - * Author: Timo Schulz, Nikos Mavrogiannopoulos - * - * This file is part of GnuTLS. - * - * The GnuTLS 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -#ifndef OPENPGP_LOCAL_H -#define OPENPGP_LOCAL_H - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef ENABLE_OPENPGP - -#include <opencdk/opencdk.h> -#include <gnutls/openpgp.h> - -#define KEYID_IMPORT(dst, src) { \ - dst[0] = _gnutls_read_uint32( src); \ - dst[1] = _gnutls_read_uint32( src+4); } - -/* Internal context to store the OpenPGP key. */ -typedef struct gnutls_openpgp_crt_int { - cdk_kbnode_t knode; - uint8_t preferred_keyid[GNUTLS_OPENPGP_KEYID_SIZE]; - int preferred_set; -} gnutls_openpgp_crt_int; - -/* Internal context to store the private OpenPGP key. */ -typedef struct gnutls_openpgp_privkey_int { - cdk_kbnode_t knode; - uint8_t preferred_keyid[GNUTLS_OPENPGP_KEYID_SIZE]; - int preferred_set; -} gnutls_openpgp_privkey_int; - - -typedef struct gnutls_openpgp_keyring_int { - cdk_keydb_hd_t db; -} gnutls_openpgp_keyring_int; - -int _gnutls_map_cdk_rc(int rc); - -int _gnutls_openpgp_export(cdk_kbnode_t node, - gnutls_openpgp_crt_fmt_t format, - void *output_data, size_t * output_data_size, - int priv); - -int _gnutls_openpgp_export2(cdk_kbnode_t node, - gnutls_openpgp_crt_fmt_t format, - gnutls_datum_t * out, int priv); - -cdk_packet_t _gnutls_get_valid_subkey(cdk_kbnode_t knode, int key_type); - -unsigned int _gnutls_get_pgp_key_usage(unsigned int pgp_usage); - -int -_gnutls_openpgp_crt_get_mpis(gnutls_openpgp_crt_t cert, uint32_t keyid[2], - gnutls_pk_params_st * params); - -int -_gnutls_openpgp_privkey_get_mpis(gnutls_openpgp_privkey_t pkey, - uint32_t keyid[2], - gnutls_pk_params_st * params); - -cdk_packet_t _gnutls_openpgp_find_key(cdk_kbnode_t knode, - uint32_t keyid[2], - unsigned int priv); - -int _gnutls_read_pgp_mpi(cdk_packet_t pkt, unsigned int priv, size_t idx, - bigint_t * m); - -int _gnutls_openpgp_find_subkey_idx(cdk_kbnode_t knode, uint32_t keyid[2], - unsigned int priv); - -int _gnutls_openpgp_get_algo(int cdk_algo); - -#endif /* ENABLE_OPENPGP */ - -#endif /* OPENPGP_LOCAL_H */ diff --git a/lib/openpgp/output.c b/lib/openpgp/output.c deleted file mode 100644 index d9127c6150..0000000000 --- a/lib/openpgp/output.c +++ /dev/null @@ -1,589 +0,0 @@ -/* - * Copyright (C) 2007-2012 Free Software Foundation, Inc. - * - * Author: Simon Josefsson, Nikos Mavrogiannopoulos - * - * This file is part of GnuTLS. - * - * The GnuTLS 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -/* Functions for printing X.509 Certificate structures - */ - -#include "gnutls_int.h" -#include <gnutls/openpgp.h> -#include "errors.h" -#include <extras/randomart.h> - -#define addf _gnutls_buffer_append_printf -#define adds _gnutls_buffer_append_str - -static void -print_key_usage(gnutls_buffer_st * str, gnutls_openpgp_crt_t cert, - unsigned int idx) -{ - unsigned int key_usage; - int err; - - adds(str, _("\t\tKey Usage:\n")); - - - if (idx == (unsigned int) -1) - err = gnutls_openpgp_crt_get_key_usage(cert, &key_usage); - else - err = - gnutls_openpgp_crt_get_subkey_usage(cert, idx, - &key_usage); - if (err < 0) { - addf(str, _("error: get_key_usage: %s\n"), - gnutls_strerror(err)); - return; - } - - if (key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE) - adds(str, _("\t\t\tDigital signatures.\n")); - if (key_usage & GNUTLS_KEY_KEY_ENCIPHERMENT) - adds(str, _("\t\t\tCommunications encipherment.\n")); - if (key_usage & GNUTLS_KEY_DATA_ENCIPHERMENT) - adds(str, _("\t\t\tStorage data encipherment.\n")); - if (key_usage & GNUTLS_KEY_KEY_AGREEMENT) - adds(str, _("\t\t\tAuthentication.\n")); - if (key_usage & GNUTLS_KEY_KEY_CERT_SIGN) - adds(str, _("\t\t\tCertificate signing.\n")); -} - -/* idx == -1 indicates main key - * otherwise the subkey. - */ -static void -print_key_id(gnutls_buffer_st * str, gnutls_openpgp_crt_t cert, int idx) -{ - gnutls_openpgp_keyid_t id; - int err; - - if (idx < 0) - err = gnutls_openpgp_crt_get_key_id(cert, id); - else - err = gnutls_openpgp_crt_get_subkey_id(cert, idx, id); - - if (err < 0) - addf(str, "error: get_key_id: %s\n", gnutls_strerror(err)); - else { - adds(str, _("\tID (hex): ")); - _gnutls_buffer_hexprint(str, id, sizeof(id)); - addf(str, "\n"); - } - -} - -/* idx == -1 indicates main key - * otherwise the subkey. - */ -static void -print_key_fingerprint(gnutls_buffer_st * str, gnutls_openpgp_crt_t cert) -{ - uint8_t fpr[128]; - size_t fpr_size = sizeof(fpr); - int err; - const char *name; - char *p; - unsigned int bits; - - err = gnutls_openpgp_crt_get_fingerprint(cert, fpr, &fpr_size); - if (err < 0) - addf(str, "error: get_fingerprint: %s\n", - gnutls_strerror(err)); - else { - adds(str, _("\tFingerprint (hex): ")); - _gnutls_buffer_hexprint(str, fpr, fpr_size); - addf(str, "\n"); - } - - err = gnutls_openpgp_crt_get_pk_algorithm(cert, &bits); - if (err < 0) - return; - - name = gnutls_pk_get_name(err); - if (name == NULL) - return; - - p = _gnutls_key_fingerprint_randomart(fpr, fpr_size, name, bits, - "\t\t"); - if (p == NULL) - return; - - adds(str, _("\tFingerprint's random art:\n")); - adds(str, p); - adds(str, "\n"); - - gnutls_free(p); -} - -static void -print_key_revoked(gnutls_buffer_st * str, gnutls_openpgp_crt_t cert, - int idx) -{ - int err; - - if (idx < 0) - err = gnutls_openpgp_crt_get_revoked_status(cert); - else - err = - gnutls_openpgp_crt_get_subkey_revoked_status(cert, - idx); - - if (err != 0) - adds(str, _("\tRevoked: True\n")); - else - adds(str, _("\tRevoked: False\n")); -} - -static void -print_key_times(gnutls_buffer_st * str, gnutls_openpgp_crt_t cert, int idx) -{ - time_t tim; - - adds(str, _("\tTime stamps:\n")); - - if (idx == -1) - tim = gnutls_openpgp_crt_get_creation_time(cert); - else - tim = - gnutls_openpgp_crt_get_subkey_creation_time(cert, idx); - - { - char s[42]; - size_t max = sizeof(s); - struct tm t; - - if (gmtime_r(&tim, &t) == NULL) - addf(str, "error: gmtime_r (%ld)\n", - (unsigned long) tim); - else if (strftime(s, max, "%a %b %d %H:%M:%S UTC %Y", &t) - == 0) - addf(str, "error: strftime (%ld)\n", - (unsigned long) tim); - else - addf(str, _("\t\tCreation: %s\n"), s); - } - - if (idx == -1) - tim = gnutls_openpgp_crt_get_expiration_time(cert); - else - tim = - gnutls_openpgp_crt_get_subkey_expiration_time(cert, - idx); - { - char s[42]; - size_t max = sizeof(s); - struct tm t; - - if (tim == 0) { - adds(str, _("\t\tExpiration: Never\n")); - } else { - if (gmtime_r(&tim, &t) == NULL) - addf(str, "error: gmtime_r (%ld)\n", - (unsigned long) tim); - else if (strftime - (s, max, "%a %b %d %H:%M:%S UTC %Y", - &t) == 0) - addf(str, "error: strftime (%ld)\n", - (unsigned long) tim); - else - addf(str, _("\t\tExpiration: %s\n"), s); - } - } -} - -static void -print_key_info(gnutls_buffer_st * str, gnutls_openpgp_crt_t cert, int idx) -{ - int err; - unsigned int bits; - - if (idx == -1) - err = gnutls_openpgp_crt_get_pk_algorithm(cert, &bits); - else - err = - gnutls_openpgp_crt_get_subkey_pk_algorithm(cert, idx, - &bits); - - if (err < 0) - addf(str, "error: get_pk_algorithm: %s\n", - gnutls_strerror(err)); - else { - const char *name = gnutls_pk_algorithm_get_name(err); - if (name == NULL) - name = _("unknown"); - - addf(str, _("\tPublic Key Algorithm: %s\n"), name); - addf(str, _("\tKey Security Level: %s\n"), - gnutls_sec_param_get_name(gnutls_pk_bits_to_sec_param - (err, bits))); - - switch (err) { - case GNUTLS_PK_RSA: - { - gnutls_datum_t m, e; - - if (idx == -1) - err = - gnutls_openpgp_crt_get_pk_rsa_raw - (cert, &m, &e); - else - err = - gnutls_openpgp_crt_get_subkey_pk_rsa_raw - (cert, idx, &m, &e); - - if (err < 0) - addf(str, - "error: get_pk_rsa_raw: %s\n", - gnutls_strerror(err)); - else { - addf(str, - _("\t\tModulus (bits %d):\n"), - bits); - _gnutls_buffer_hexdump(str, m.data, - m.size, - "\t\t\t"); - adds(str, _("\t\tExponent:\n")); - _gnutls_buffer_hexdump(str, e.data, - e.size, - "\t\t\t"); - - gnutls_free(m.data); - gnutls_free(e.data); - } - - } - break; - - case GNUTLS_PK_DSA: - { - gnutls_datum_t p, q, g, y; - - if (idx == -1) - err = - gnutls_openpgp_crt_get_pk_dsa_raw - (cert, &p, &q, &g, &y); - else - err = - gnutls_openpgp_crt_get_subkey_pk_dsa_raw - (cert, idx, &p, &q, &g, &y); - if (err < 0) - addf(str, - "error: get_pk_dsa_raw: %s\n", - gnutls_strerror(err)); - else { - addf(str, - _ - ("\t\tPublic key (bits %d):\n"), - bits); - adds(str, _("\t\tY:\n")); - _gnutls_buffer_hexdump(str, y.data, - y.size, - "\t\t\t"); - adds(str, _("\t\tP:\n")); - _gnutls_buffer_hexdump(str, p.data, - p.size, - "\t\t\t"); - adds(str, _("\t\tQ:\n")); - _gnutls_buffer_hexdump(str, q.data, - q.size, - "\t\t\t"); - adds(str, _("\t\tG:\n")); - _gnutls_buffer_hexdump(str, g.data, - g.size, - "\t\t\t"); - - gnutls_free(p.data); - gnutls_free(q.data); - gnutls_free(g.data); - gnutls_free(y.data); - adds(str, "\n"); - } - } - break; - - default: - break; - } - } -} - -static void print_cert(gnutls_buffer_st * str, gnutls_openpgp_crt_t cert) -{ - int i, subkeys; - int err; - - print_key_revoked(str, cert, -1); - - /* Version. */ - { - int version = gnutls_openpgp_crt_get_version(cert); - if (version < 0) - addf(str, "error: get_version: %s\n", - gnutls_strerror(version)); - else - addf(str, _("\tVersion: %d\n"), version); - } - - /* ID. */ - print_key_id(str, cert, -1); - - print_key_fingerprint(str, cert); - - /* Names. */ - i = 0; - do { - char *dn; - size_t dn_size = 0; - - err = gnutls_openpgp_crt_get_name(cert, i, NULL, &dn_size); - if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) - break; - - if (err != GNUTLS_E_SHORT_MEMORY_BUFFER) { - addf(str, "error: get_name: %s\n", - gnutls_strerror(err)); - } else { - dn = gnutls_malloc(dn_size); - if (!dn) - addf(str, "error: malloc (%d): %s\n", - (int) dn_size, - gnutls_strerror - (GNUTLS_E_MEMORY_ERROR)); - else { - err = - gnutls_openpgp_crt_get_name(cert, i, - dn, - &dn_size); - if (err < 0 - && err != - GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE - && err != GNUTLS_E_OPENPGP_UID_REVOKED) - addf(str, "error: get_name: %s\n", - gnutls_strerror(err)); - else if (err >= 0) - addf(str, _("\tName[%d]: %s\n"), i, - dn); - else if (err == - GNUTLS_E_OPENPGP_UID_REVOKED) - addf(str, - _("\tRevoked Name[%d]: %s\n"), - i, dn); - - gnutls_free(dn); - } - } - - i++; - } - while (err >= 0); - - print_key_times(str, cert, -1); - - print_key_info(str, cert, -1); - print_key_usage(str, cert, -1); - - subkeys = gnutls_openpgp_crt_get_subkey_count(cert); - if (subkeys < 0) - return; - - for (i = 0; i < subkeys; i++) { - addf(str, _("\n\tSubkey[%d]:\n"), i); - - print_key_revoked(str, cert, i); - print_key_id(str, cert, i); - print_key_times(str, cert, i); - print_key_info(str, cert, i); - print_key_usage(str, cert, i); - } - -} - -static void -print_oneline(gnutls_buffer_st * str, gnutls_openpgp_crt_t cert) -{ - int err, i; - - i = 0; - do { - char *dn; - size_t dn_size = 0; - - err = gnutls_openpgp_crt_get_name(cert, i, NULL, &dn_size); - if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) - break; - - if (err != GNUTLS_E_SHORT_MEMORY_BUFFER) { - addf(str, "unknown name (%s), ", - gnutls_strerror(err)); - } else { - dn = gnutls_malloc(dn_size); - if (!dn) - addf(str, "unknown name (%s), ", - gnutls_strerror - (GNUTLS_E_MEMORY_ERROR)); - else { - err = - gnutls_openpgp_crt_get_name(cert, i, - dn, - &dn_size); - if (err < 0 - && err != - GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE - && err != GNUTLS_E_OPENPGP_UID_REVOKED) - addf(str, "unknown name (%s), ", - gnutls_strerror(err)); - else if (err >= 0) - addf(str, _("name[%d]: %s, "), i, - dn); - else if (err == - GNUTLS_E_OPENPGP_UID_REVOKED) - addf(str, - _("revoked name[%d]: %s, "), - i, dn); - - gnutls_free(dn); - } - } - - i++; - } - while (err >= 0); - - { - char fpr[128]; - size_t fpr_size = sizeof(fpr); - - err = - gnutls_openpgp_crt_get_fingerprint(cert, fpr, - &fpr_size); - if (err < 0) - addf(str, "error: get_fingerprint: %s\n", - gnutls_strerror(err)); - else { - adds(str, _("fingerprint: ")); - _gnutls_buffer_hexprint(str, fpr, fpr_size); - addf(str, ", "); - } - } - - { - time_t tim; - - tim = gnutls_openpgp_crt_get_creation_time(cert); - { - char s[42]; - size_t max = sizeof(s); - struct tm t; - - if (gmtime_r(&tim, &t) == NULL) - addf(str, "error: gmtime_r (%ld), ", - (unsigned long) tim); - else if (strftime - (s, max, "%Y-%m-%d %H:%M:%S UTC", - &t) == 0) - addf(str, "error: strftime (%ld), ", - (unsigned long) tim); - else - addf(str, _("created: %s, "), s); - } - - tim = gnutls_openpgp_crt_get_expiration_time(cert); - { - char s[42]; - size_t max = sizeof(s); - struct tm t; - - if (tim == 0) - adds(str, _("never expires, ")); - else { - if (gmtime_r(&tim, &t) == NULL) - addf(str, - "error: gmtime_r (%ld), ", - (unsigned long) tim); - else if (strftime - (s, max, "%Y-%m-%d %H:%M:%S UTC", - &t) == 0) - addf(str, - "error: strftime (%ld), ", - (unsigned long) tim); - else - addf(str, _("expires: %s, "), s); - } - } - } - - { - unsigned int bits = 0; - gnutls_pk_algorithm_t algo = - gnutls_openpgp_crt_get_pk_algorithm(cert, &bits); - const char *algostr = gnutls_pk_algorithm_get_name(algo); - - if (algostr) - addf(str, _("key algorithm %s (%d bits)"), algostr, - bits); - else - addf(str, _("unknown key algorithm (%d)"), algo); - } -} - -/** - * gnutls_openpgp_crt_print: - * @cert: The structure to be printed - * @format: Indicate the format to use - * @out: Newly allocated datum with (0) terminated string. - * - * This function will pretty print an OpenPGP certificate, suitable - * for display to a human. - * - * The format should be (0) for future compatibility. - * - * The output @out needs to be deallocate using gnutls_free(). - * - * Returns: %GNUTLS_E_SUCCESS on success, or an error code. - **/ -int -gnutls_openpgp_crt_print(gnutls_openpgp_crt_t cert, - gnutls_certificate_print_formats_t format, - gnutls_datum_t * out) -{ - gnutls_buffer_st str; - int ret; - - _gnutls_buffer_init(&str); - - if (format == GNUTLS_CRT_PRINT_ONELINE) { - print_oneline(&str, cert); - } else if (format == GNUTLS_CRT_PRINT_COMPACT) { - print_oneline(&str, cert); - - ret = _gnutls_buffer_append_data(&str, "\n", 1); - if (ret < 0) - return gnutls_assert_val(ret); - - print_key_fingerprint(&str, cert); - } else { - _gnutls_buffer_append_str(&str, - _ - ("OpenPGP Certificate Information:\n")); - print_cert(&str, cert); - } - - return _gnutls_buffer_to_datum(&str, out, 1); -} diff --git a/lib/openpgp/pgp.c b/lib/openpgp/pgp.c deleted file mode 100644 index 03a507d4c4..0000000000 --- a/lib/openpgp/pgp.c +++ /dev/null @@ -1,1780 +0,0 @@ -/* - * Copyright (C) 2002-2012 Free Software Foundation, Inc. - * - * Author: Timo Schulz, Nikos Mavrogiannopoulos - * - * This file is part of GnuTLS. - * - * The GnuTLS 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -/* Functions on OpenPGP key parsing - */ - -#include "gnutls_int.h" -#include <datum.h> -#include <global.h> -#include "errors.h" -#include <openpgp_int.h> -#include <str.h> -#include <num.h> -#include <x509/common.h> - -/** - * gnutls_openpgp_crt_init: - * @key: A pointer to the type to be initialized - * - * This function will initialize an OpenPGP key structure. - * - * Returns: %GNUTLS_E_SUCCESS on success, or an error code. - **/ -int gnutls_openpgp_crt_init(gnutls_openpgp_crt_t * key) -{ - *key = gnutls_calloc(1, sizeof(gnutls_openpgp_crt_int)); - - if (*key) - return 0; /* success */ - return GNUTLS_E_MEMORY_ERROR; -} - -/** - * gnutls_openpgp_crt_deinit: - * @key: A pointer to the type to be initialized - * - * This function will deinitialize a key structure. - **/ -void gnutls_openpgp_crt_deinit(gnutls_openpgp_crt_t key) -{ - if (!key) - return; - - if (key->knode) { - cdk_kbnode_release(key->knode); - key->knode = NULL; - } - - gnutls_free(key); -} - -/** - * gnutls_openpgp_crt_import: - * @key: The structure to store the parsed key. - * @data: The RAW or BASE64 encoded key. - * @format: One of gnutls_openpgp_crt_fmt_t elements. - * - * This function will convert the given RAW or Base64 encoded key to - * the native #gnutls_openpgp_crt_t format. The output will be stored - * in 'key'. - * - * Returns: %GNUTLS_E_SUCCESS on success, or an error code. - **/ -int -gnutls_openpgp_crt_import(gnutls_openpgp_crt_t key, - const gnutls_datum_t * data, - gnutls_openpgp_crt_fmt_t format) -{ - cdk_packet_t pkt; - int rc, armor; - - if (data->data == NULL || data->size == 0) { - gnutls_assert(); - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - } - - if (format == GNUTLS_OPENPGP_FMT_RAW) - armor = 0; - else - armor = 1; - - rc = cdk_kbnode_read_from_mem(&key->knode, armor, data->data, - data->size, 1); - if (rc) { - rc = _gnutls_map_cdk_rc(rc); - gnutls_assert(); - return rc; - } - - /* Test if the import was successful. */ - pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_PUBLIC_KEY); - if (pkt == NULL) { - gnutls_assert(); - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - } - - return 0; -} - -int _gnutls_openpgp_export2(cdk_kbnode_t node, - gnutls_openpgp_crt_fmt_t format, - gnutls_datum_t * out, int priv) -{ - int ret; - size_t size = 0; - - ret = _gnutls_openpgp_export(node, format, NULL, &size, priv); - if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) { - out->data = gnutls_malloc(size); - - ret = - _gnutls_openpgp_export(node, format, out->data, &size, - priv); - if (ret < 0) { - gnutls_free(out->data); - return gnutls_assert_val(ret); - } - out->size = size; - } else if (ret < 0) - return gnutls_assert_val(ret); - - return 0; -} - -/* internal version of export - */ -int -_gnutls_openpgp_export(cdk_kbnode_t node, - gnutls_openpgp_crt_fmt_t format, - void *output_data, - size_t * output_data_size, int priv) -{ - size_t input_data_size = *output_data_size; - size_t calc_size; - int rc; - - rc = cdk_kbnode_write_to_mem(node, output_data, output_data_size); - if (rc) { - rc = _gnutls_map_cdk_rc(rc); - gnutls_assert(); - return rc; - } - - /* If the caller uses output_data == NULL then return what he expects. - */ - if (!output_data && format != GNUTLS_OPENPGP_FMT_BASE64) { - gnutls_assert(); - return GNUTLS_E_SHORT_MEMORY_BUFFER; - } - - if (format == GNUTLS_OPENPGP_FMT_BASE64) { - unsigned char *in = gnutls_calloc(1, *output_data_size); - if (in == NULL) - return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); - - rc = cdk_kbnode_write_to_mem(node, in, output_data_size); - if (rc) { - gnutls_free(in); - rc = _gnutls_map_cdk_rc(rc); - gnutls_assert(); - return rc; - } - - /* Calculate the size of the encoded data and check if the provided - buffer is large enough. */ - rc = cdk_armor_encode_buffer(in, *output_data_size, - NULL, 0, &calc_size, - priv ? CDK_ARMOR_SECKEY : - CDK_ARMOR_PUBKEY); - if (rc || calc_size > input_data_size) { - gnutls_free(in); - *output_data_size = calc_size; - gnutls_assert(); - return GNUTLS_E_SHORT_MEMORY_BUFFER; - } - - rc = cdk_armor_encode_buffer(in, *output_data_size, - output_data, input_data_size, - &calc_size, - priv ? CDK_ARMOR_SECKEY : - CDK_ARMOR_PUBKEY); - gnutls_free(in); - *output_data_size = calc_size; - - if (rc) { - rc = _gnutls_map_cdk_rc(rc); - gnutls_assert(); - return rc; - } - } - - return 0; - -} - -/** - * gnutls_openpgp_crt_export: - * @key: Holds the key. - * @format: One of gnutls_openpgp_crt_fmt_t elements. - * @output_data: will contain the raw or base64 encoded key - * @output_data_size: holds the size of output_data (and will - * be replaced by the actual size of parameters) - * - * This function will convert the given key to RAW or Base64 format. - * If the buffer provided is not long enough to hold the output, then - * %GNUTLS_E_SHORT_MEMORY_BUFFER will be returned. - * - * Returns: %GNUTLS_E_SUCCESS on success, or an error code. - **/ -int -gnutls_openpgp_crt_export(gnutls_openpgp_crt_t key, - gnutls_openpgp_crt_fmt_t format, - void *output_data, size_t * output_data_size) -{ - return _gnutls_openpgp_export(key->knode, format, output_data, - output_data_size, 0); -} - -/** - * gnutls_openpgp_crt_export2: - * @key: Holds the key. - * @format: One of gnutls_openpgp_crt_fmt_t elements. - * @out: will contain the raw or base64 encoded key - * - * This function will convert the given key to RAW or Base64 format. - * The output buffer is allocated using gnutls_malloc(). - * - * Returns: %GNUTLS_E_SUCCESS on success, or an error code. - * - * Since: 3.1.3 - **/ -int -gnutls_openpgp_crt_export2(gnutls_openpgp_crt_t key, - gnutls_openpgp_crt_fmt_t format, - gnutls_datum_t * out) -{ - return _gnutls_openpgp_export2(key->knode, format, out, 0); -} - -/** - * gnutls_openpgp_crt_get_fingerprint: - * @key: the raw data that contains the OpenPGP public key. - * @fpr: the buffer to save the fingerprint, must hold at least 20 bytes. - * @fprlen: the integer to save the length of the fingerprint. - * - * Get key fingerprint. Depending on the algorithm, the fingerprint - * can be 16 or 20 bytes. - * - * Returns: On success, 0 is returned. Otherwise, an error code. - **/ -int -gnutls_openpgp_crt_get_fingerprint(gnutls_openpgp_crt_t key, - void *fpr, size_t * fprlen) -{ - cdk_packet_t pkt; - cdk_pkt_pubkey_t pk = NULL; - - if (!fpr || !fprlen) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - *fprlen = 0; - - pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_PUBLIC_KEY); - if (!pkt) - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - - pk = pkt->pkt.public_key; - *fprlen = 20; - - /* FIXME: Check if the draft allows old PGP keys. */ - if (is_RSA(pk->pubkey_algo) && pk->version < 4) - *fprlen = 16; - cdk_pk_get_fingerprint(pk, fpr); - - return 0; -} - -static int _gnutls_openpgp_count_key_names(gnutls_openpgp_crt_t key) -{ - cdk_kbnode_t p, ctx; - cdk_packet_t pkt; - int nuids; - - if (key == NULL) { - gnutls_assert(); - return 0; - } - - ctx = NULL; - nuids = 0; - while ((p = cdk_kbnode_walk(key->knode, &ctx, 0))) { - pkt = cdk_kbnode_get_packet(p); - if (pkt->pkttype == CDK_PKT_USER_ID) - nuids++; - } - - return nuids; -} - - -/** - * gnutls_openpgp_crt_get_name: - * @key: the structure that contains the OpenPGP public key. - * @idx: the index of the ID to extract - * @buf: a pointer to a structure to hold the name, may be %NULL - * to only get the @sizeof_buf. - * @sizeof_buf: holds the maximum size of @buf, on return hold the - * actual/required size of @buf. - * - * Extracts the userID from the parsed OpenPGP key. - * - * Returns: %GNUTLS_E_SUCCESS on success, and if the index of the ID - * does not exist %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE, or an - * error code. - **/ -int -gnutls_openpgp_crt_get_name(gnutls_openpgp_crt_t key, - int idx, char *buf, size_t * sizeof_buf) -{ - cdk_kbnode_t ctx = NULL, p; - cdk_packet_t pkt = NULL; - cdk_pkt_userid_t uid = NULL; - int pos = 0; - - if (!key) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - if (idx < 0 || idx >= _gnutls_openpgp_count_key_names(key)) - return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; - - pos = 0; - while ((p = cdk_kbnode_walk(key->knode, &ctx, 0))) { - pkt = cdk_kbnode_get_packet(p); - if (pkt->pkttype == CDK_PKT_USER_ID) { - if (pos == idx) - break; - pos++; - } - } - - if (!pkt) { - gnutls_assert(); - return GNUTLS_E_INTERNAL_ERROR; - } - - uid = pkt->pkt.user_id; - if (uid->len >= *sizeof_buf) { - gnutls_assert(); - *sizeof_buf = uid->len + 1; - return GNUTLS_E_SHORT_MEMORY_BUFFER; - } - - if (buf) { - memcpy(buf, uid->name, uid->len); - buf[uid->len] = '\0'; /* make sure it's a string */ - } - *sizeof_buf = uid->len + 1; - - if (uid->is_revoked) - return GNUTLS_E_OPENPGP_UID_REVOKED; - - return 0; -} - -/** - * gnutls_openpgp_crt_get_pk_algorithm: - * @key: is an OpenPGP key - * @bits: if bits is non null it will hold the size of the parameters' in bits - * - * This function will return the public key algorithm of an OpenPGP - * certificate. - * - * If bits is non null, it should have enough size to hold the parameters - * size in bits. For RSA the bits returned is the modulus. - * For DSA the bits returned are of the public exponent. - * - * Returns: a member of the #gnutls_pk_algorithm_t enumeration on - * success, or GNUTLS_PK_UNKNOWN on error. - **/ -gnutls_pk_algorithm_t -gnutls_openpgp_crt_get_pk_algorithm(gnutls_openpgp_crt_t key, - unsigned int *bits) -{ - cdk_packet_t pkt; - int algo = 0, ret; - uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; - - if (!key) { - gnutls_assert(); - return GNUTLS_PK_UNKNOWN; - } - - ret = gnutls_openpgp_crt_get_preferred_key_id(key, keyid); - if (ret == 0) { - int idx; - - idx = gnutls_openpgp_crt_get_subkey_idx(key, keyid); - if (idx != GNUTLS_OPENPGP_MASTER_KEYID_IDX) { - algo = - gnutls_openpgp_crt_get_subkey_pk_algorithm(key, - idx, - bits); - return algo; - } - } - - pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_PUBLIC_KEY); - if (pkt) { - if (bits) - *bits = cdk_pk_get_nbits(pkt->pkt.public_key); - algo = - _gnutls_openpgp_get_algo(pkt->pkt.public_key-> - pubkey_algo); - } - - return algo; -} - - -/** - * gnutls_openpgp_crt_get_version: - * @key: the structure that contains the OpenPGP public key. - * - * Extract the version of the OpenPGP key. - * - * Returns: the version number is returned, or a negative error code on errors. - **/ -int gnutls_openpgp_crt_get_version(gnutls_openpgp_crt_t key) -{ - cdk_packet_t pkt; - int version; - - if (!key) - return -1; - - pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_PUBLIC_KEY); - if (pkt) - version = pkt->pkt.public_key->version; - else - version = 0; - - return version; -} - - -/** - * gnutls_openpgp_crt_get_creation_time: - * @key: the structure that contains the OpenPGP public key. - * - * Get key creation time. - * - * Returns: the timestamp when the OpenPGP key was created. - **/ -time_t gnutls_openpgp_crt_get_creation_time(gnutls_openpgp_crt_t key) -{ - cdk_packet_t pkt; - time_t timestamp; - - if (!key) - return (time_t) - 1; - - pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_PUBLIC_KEY); - if (pkt) - timestamp = pkt->pkt.public_key->timestamp; - else - timestamp = 0; - - return timestamp; -} - - -/** - * gnutls_openpgp_crt_get_expiration_time: - * @key: the structure that contains the OpenPGP public key. - * - * Get key expiration time. A value of '0' means that the key doesn't - * expire at all. - * - * Returns: the time when the OpenPGP key expires. - **/ -time_t gnutls_openpgp_crt_get_expiration_time(gnutls_openpgp_crt_t key) -{ - cdk_packet_t pkt; - time_t expiredate; - - if (!key) - return (time_t) - 1; - - pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_PUBLIC_KEY); - if (pkt) - expiredate = pkt->pkt.public_key->expiredate; - else - expiredate = 0; - - return expiredate; -} - -/** - * gnutls_openpgp_crt_get_key_id: - * @key: the structure that contains the OpenPGP public key. - * @keyid: the buffer to save the keyid. - * - * Get key id string. - * - * Returns: the 64-bit keyID of the OpenPGP key. - * - * Since: 2.4.0 - **/ -int -gnutls_openpgp_crt_get_key_id(gnutls_openpgp_crt_t key, - gnutls_openpgp_keyid_t keyid) -{ - cdk_packet_t pkt; - uint32_t kid[2]; - - if (!key || !keyid) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_PUBLIC_KEY); - if (!pkt) - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - - cdk_pk_get_keyid(pkt->pkt.public_key, kid); - _gnutls_write_uint32(kid[0], keyid); - _gnutls_write_uint32(kid[1], keyid + 4); - - return 0; -} - -/** - * gnutls_openpgp_crt_get_revoked_status: - * @key: the structure that contains the OpenPGP public key. - * - * Get revocation status of key. - * - * Returns: true (1) if the key has been revoked, or false (0) if it - * has not. - * - * Since: 2.4.0 - **/ -int gnutls_openpgp_crt_get_revoked_status(gnutls_openpgp_crt_t key) -{ - cdk_packet_t pkt; - - if (!key) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_PUBLIC_KEY); - if (!pkt) - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - - if (pkt->pkt.public_key->is_revoked != 0) - return 1; - return 0; -} - -/** - * gnutls_openpgp_crt_check_hostname: - * @key: should contain a #gnutls_openpgp_crt_t type - * @hostname: A null terminated string that contains a DNS name - * - * This function will check if the given key's owner matches the - * given hostname. This is a basic implementation of the matching - * described in RFC2818 (HTTPS), which takes into account wildcards. - * - * Returns: non-zero for a successful match, and zero on failure. - **/ -int -gnutls_openpgp_crt_check_hostname(gnutls_openpgp_crt_t key, - const char *hostname) -{ - return gnutls_openpgp_crt_check_hostname2(key, hostname, 0); -} - -/** - * gnutls_openpgp_crt_check_hostname2: - * @key: should contain a #gnutls_openpgp_crt_t type - * @hostname: A null terminated string that contains a DNS name - * @flags: gnutls_certificate_verify_flags - * - * This function will check if the given key's owner matches the - * given hostname. - * - * Unless, the flag %GNUTLS_VERIFY_DO_NOT_ALLOW_WILDCARDS is specified, - * wildcards are only considered if the domain name consists of three - * components or more, and the wildcard starts at the leftmost position. - * - * Returns: non-zero for a successful match, and zero on failure. - **/ -int -gnutls_openpgp_crt_check_hostname2(gnutls_openpgp_crt_t key, - const char *hostname, unsigned flags) -{ - char dnsname[MAX_CN]; - size_t dnsnamesize; - int ret = 0; - int i; - - /* Check through all included names. */ - for (i = 0; !(ret < 0); i++) { - dnsnamesize = sizeof(dnsname); - ret = - gnutls_openpgp_crt_get_name(key, i, dnsname, - &dnsnamesize); - - if (ret == 0) { - /* Length returned by gnutls_openpgp_crt_get_name includes - the terminating (0). */ - dnsnamesize--; - - if (_gnutls_hostname_compare - (dnsname, dnsnamesize, hostname, flags)) - return 1; - } - } - - /* not found a matching name */ - return 0; -} - -/** - * gnutls_openpgp_crt_check_email: - * @key: should contain a #gnutls_openpgp_crt_t type - * @email: A null terminated string that contains an RFC822 address (email) - * @flags: gnutls_certificate_verify_flags - * - * This function will check if the given key's owner matches the - * given email address. - * - * Returns: non-zero for a successful match, and zero on failure. - **/ -int -gnutls_openpgp_crt_check_email(gnutls_openpgp_crt_t key, - const char *email, unsigned flags) -{ - char rfc822name[MAX_CN]; - size_t rfc822name_size; - int ret = 0; - int i; - - /* Check through all included names. */ - for (i = 0; !(ret < 0); i++) { - rfc822name_size = sizeof(rfc822name); - ret = - gnutls_openpgp_crt_get_name(key, i, rfc822name, - &rfc822name_size); - - if (ret == 0) { - /* Length returned by gnutls_openpgp_crt_get_name includes - the terminating (0). */ - rfc822name_size--; - - if (_gnutls_hostname_compare - (rfc822name, rfc822name_size, email, GNUTLS_VERIFY_DO_NOT_ALLOW_WILDCARDS)) - return 1; - } - } - - /* not found a matching name */ - return 0; -} - -unsigned int _gnutls_get_pgp_key_usage(unsigned int cdk_usage) -{ - unsigned int usage = 0; - - if (cdk_usage & CDK_KEY_USG_CERT_SIGN) - usage |= GNUTLS_KEY_KEY_CERT_SIGN; - if (cdk_usage & CDK_KEY_USG_DATA_SIGN) - usage |= GNUTLS_KEY_DIGITAL_SIGNATURE; - if (cdk_usage & CDK_KEY_USG_COMM_ENCR) - usage |= GNUTLS_KEY_KEY_ENCIPHERMENT; - if (cdk_usage & CDK_KEY_USG_STORAGE_ENCR) - usage |= GNUTLS_KEY_DATA_ENCIPHERMENT; - if (cdk_usage & CDK_KEY_USG_AUTH) - usage |= GNUTLS_KEY_KEY_AGREEMENT; - - return usage; -} - -/** - * gnutls_openpgp_crt_get_key_usage: - * @key: should contain a gnutls_openpgp_crt_t type - * @key_usage: where the key usage bits will be stored - * - * This function will return certificate's key usage, by checking the - * key algorithm. The key usage value will ORed values of the: - * %GNUTLS_KEY_DIGITAL_SIGNATURE, %GNUTLS_KEY_KEY_ENCIPHERMENT. - * - * Returns: %GNUTLS_E_SUCCESS on success, or an error code. - */ -int -gnutls_openpgp_crt_get_key_usage(gnutls_openpgp_crt_t key, - unsigned int *key_usage) -{ - cdk_packet_t pkt; - - if (!key) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_PUBLIC_KEY); - if (!pkt) - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - - *key_usage = - _gnutls_get_pgp_key_usage(pkt->pkt.public_key->pubkey_usage); - - return 0; -} - -/** - * gnutls_openpgp_crt_get_subkey_count: - * @key: is an OpenPGP key - * - * This function will return the number of subkeys present in the - * given OpenPGP certificate. - * - * Returns: the number of subkeys, or a negative error code on error. - * - * Since: 2.4.0 - **/ -int gnutls_openpgp_crt_get_subkey_count(gnutls_openpgp_crt_t key) -{ - cdk_kbnode_t p, ctx; - cdk_packet_t pkt; - int subkeys; - - if (key == NULL) { - gnutls_assert(); - return 0; - } - - ctx = NULL; - subkeys = 0; - while ((p = cdk_kbnode_walk(key->knode, &ctx, 0))) { - pkt = cdk_kbnode_get_packet(p); - if (pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY) - subkeys++; - } - - return subkeys; -} - -/* returns the subkey with the given index */ -static cdk_packet_t -_get_public_subkey(gnutls_openpgp_crt_t key, unsigned int indx) -{ - cdk_kbnode_t p, ctx; - cdk_packet_t pkt; - unsigned int subkeys; - - if (key == NULL) { - gnutls_assert(); - return NULL; - } - - ctx = NULL; - subkeys = 0; - while ((p = cdk_kbnode_walk(key->knode, &ctx, 0))) { - pkt = cdk_kbnode_get_packet(p); - if (pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY - && indx == subkeys++) - return pkt; - } - - return NULL; -} - -/* returns the key with the given keyid. It can be either key or subkey. - * depending on what requested: - * pkt->pkt.secret_key; - * pkt->pkt.public_key; - */ -cdk_packet_t -_gnutls_openpgp_find_key(cdk_kbnode_t knode, uint32_t keyid[2], - unsigned int priv) -{ - cdk_kbnode_t p, ctx; - cdk_packet_t pkt; - uint32_t local_keyid[2]; - - ctx = NULL; - while ((p = cdk_kbnode_walk(knode, &ctx, 0))) { - pkt = cdk_kbnode_get_packet(p); - - if ((priv == 0 - && (pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY - || pkt->pkttype == CDK_PKT_PUBLIC_KEY)) - || (priv != 0 - && (pkt->pkttype == CDK_PKT_SECRET_SUBKEY - || pkt->pkttype == CDK_PKT_SECRET_KEY))) { - if (priv == 0) - cdk_pk_get_keyid(pkt->pkt.public_key, - local_keyid); - else - cdk_pk_get_keyid(pkt->pkt.secret_key->pk, - local_keyid); - - if (local_keyid[0] == keyid[0] - && local_keyid[1] == keyid[1]) { - return pkt; - } - } - } - - gnutls_assert(); - return NULL; -} - -/* returns the key with the given keyid - * depending on what requested: - * pkt->pkt.secret_key; - * pkt->pkt.public_key; - */ -int -_gnutls_openpgp_find_subkey_idx(cdk_kbnode_t knode, uint32_t keyid[2], - unsigned int priv) -{ - cdk_kbnode_t p, ctx; - cdk_packet_t pkt; - int i = 0; - uint32_t local_keyid[2]; - - _gnutls_hard_log("Looking keyid: %x.%x\n", keyid[0], keyid[1]); - - ctx = NULL; - while ((p = cdk_kbnode_walk(knode, &ctx, 0))) { - pkt = cdk_kbnode_get_packet(p); - - if ((priv == 0 && (pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY)) - || (priv != 0 - && (pkt->pkttype == CDK_PKT_SECRET_SUBKEY))) { - if (priv == 0) - cdk_pk_get_keyid(pkt->pkt.public_key, - local_keyid); - else - cdk_pk_get_keyid(pkt->pkt.secret_key->pk, - local_keyid); - - _gnutls_hard_log("Found keyid: %x.%x\n", - local_keyid[0], local_keyid[1]); - if (local_keyid[0] == keyid[0] - && local_keyid[1] == keyid[1]) { - return i; - } - i++; - } - } - - gnutls_assert(); - return GNUTLS_E_OPENPGP_SUBKEY_ERROR; -} - -/** - * gnutls_openpgp_crt_get_subkey_revoked_status: - * @key: the structure that contains the OpenPGP public key. - * @idx: is the subkey index - * - * Get subkey revocation status. A negative error code indicates an error. - * - * Returns: true (1) if the key has been revoked, or false (0) if it - * has not. - * - * Since: 2.4.0 - **/ -int -gnutls_openpgp_crt_get_subkey_revoked_status(gnutls_openpgp_crt_t key, - unsigned int idx) -{ - cdk_packet_t pkt; - - if (!key) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - return gnutls_openpgp_crt_get_revoked_status(key); - - pkt = _get_public_subkey(key, idx); - if (!pkt) - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - - if (pkt->pkt.public_key->is_revoked != 0) - return 1; - return 0; -} - -/** - * gnutls_openpgp_crt_get_subkey_pk_algorithm: - * @key: is an OpenPGP key - * @idx: is the subkey index - * @bits: if bits is non null it will hold the size of the parameters' in bits - * - * This function will return the public key algorithm of a subkey of an OpenPGP - * certificate. - * - * If bits is non null, it should have enough size to hold the - * parameters size in bits. For RSA the bits returned is the modulus. - * For DSA the bits returned are of the public exponent. - * - * Returns: a member of the #gnutls_pk_algorithm_t enumeration on - * success, or GNUTLS_PK_UNKNOWN on error. - * - * Since: 2.4.0 - **/ -gnutls_pk_algorithm_t -gnutls_openpgp_crt_get_subkey_pk_algorithm(gnutls_openpgp_crt_t key, - unsigned int idx, - unsigned int *bits) -{ - cdk_packet_t pkt; - int algo; - - if (!key) { - gnutls_assert(); - return GNUTLS_PK_UNKNOWN; - } - - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - return gnutls_openpgp_crt_get_pk_algorithm(key, bits); - - pkt = _get_public_subkey(key, idx); - - algo = 0; - if (pkt) { - if (bits) - *bits = cdk_pk_get_nbits(pkt->pkt.public_key); - algo = - _gnutls_openpgp_get_algo(pkt->pkt.public_key-> - pubkey_algo); - } - - return algo; -} - -/** - * gnutls_openpgp_crt_get_subkey_creation_time: - * @key: the structure that contains the OpenPGP public key. - * @idx: the subkey index - * - * Get subkey creation time. - * - * Returns: the timestamp when the OpenPGP sub-key was created. - * - * Since: 2.4.0 - **/ -time_t -gnutls_openpgp_crt_get_subkey_creation_time(gnutls_openpgp_crt_t key, - unsigned int idx) -{ - cdk_packet_t pkt; - time_t timestamp; - - if (!key) - return (time_t) - 1; - - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - return gnutls_openpgp_crt_get_creation_time(key); - - pkt = _get_public_subkey(key, idx); - if (pkt) - timestamp = pkt->pkt.public_key->timestamp; - else - timestamp = 0; - - return timestamp; -} - - -/** - * gnutls_openpgp_crt_get_subkey_expiration_time: - * @key: the structure that contains the OpenPGP public key. - * @idx: the subkey index - * - * Get subkey expiration time. A value of '0' means that the key - * doesn't expire at all. - * - * Returns: the time when the OpenPGP key expires. - * - * Since: 2.4.0 - **/ -time_t -gnutls_openpgp_crt_get_subkey_expiration_time(gnutls_openpgp_crt_t key, - unsigned int idx) -{ - cdk_packet_t pkt; - time_t expiredate; - - if (!key) - return (time_t) - 1; - - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - return gnutls_openpgp_crt_get_expiration_time(key); - - pkt = _get_public_subkey(key, idx); - if (pkt) - expiredate = pkt->pkt.public_key->expiredate; - else - expiredate = 0; - - return expiredate; -} - -/** - * gnutls_openpgp_crt_get_subkey_id: - * @key: the structure that contains the OpenPGP public key. - * @idx: the subkey index - * @keyid: the buffer to save the keyid. - * - * Get the subkey's key-id. - * - * Returns: the 64-bit keyID of the OpenPGP key. - **/ -int -gnutls_openpgp_crt_get_subkey_id(gnutls_openpgp_crt_t key, - unsigned int idx, - gnutls_openpgp_keyid_t keyid) -{ - cdk_packet_t pkt; - uint32_t kid[2]; - - if (!key || !keyid) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - return gnutls_openpgp_crt_get_key_id(key, keyid); - - pkt = _get_public_subkey(key, idx); - if (!pkt) - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - - cdk_pk_get_keyid(pkt->pkt.public_key, kid); - _gnutls_write_uint32(kid[0], keyid); - _gnutls_write_uint32(kid[1], keyid + 4); - - return 0; -} - -/** - * gnutls_openpgp_crt_get_subkey_fingerprint: - * @key: the raw data that contains the OpenPGP public key. - * @idx: the subkey index - * @fpr: the buffer to save the fingerprint, must hold at least 20 bytes. - * @fprlen: the integer to save the length of the fingerprint. - * - * Get key fingerprint of a subkey. Depending on the algorithm, the - * fingerprint can be 16 or 20 bytes. - * - * Returns: On success, 0 is returned. Otherwise, an error code. - * - * Since: 2.4.0 - **/ -int -gnutls_openpgp_crt_get_subkey_fingerprint(gnutls_openpgp_crt_t key, - unsigned int idx, - void *fpr, size_t * fprlen) -{ - cdk_packet_t pkt; - cdk_pkt_pubkey_t pk = NULL; - - if (!fpr || !fprlen) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - return gnutls_openpgp_crt_get_fingerprint(key, fpr, - fprlen); - - *fprlen = 0; - - pkt = _get_public_subkey(key, idx); - if (!pkt) - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - - pk = pkt->pkt.public_key; - *fprlen = 20; - - /* FIXME: Check if the draft allows old PGP keys. */ - if (is_RSA(pk->pubkey_algo) && pk->version < 4) - *fprlen = 16; - cdk_pk_get_fingerprint(pk, fpr); - - return 0; -} - -/** - * gnutls_openpgp_crt_get_subkey_idx: - * @key: the structure that contains the OpenPGP public key. - * @keyid: the keyid. - * - * Get subkey's index. - * - * Returns: the index of the subkey or a negative error value. - * - * Since: 2.4.0 - **/ -int -gnutls_openpgp_crt_get_subkey_idx(gnutls_openpgp_crt_t key, - const gnutls_openpgp_keyid_t keyid) -{ - int ret; - uint32_t kid[2]; - uint8_t master_id[GNUTLS_OPENPGP_KEYID_SIZE]; - - if (!key) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - ret = gnutls_openpgp_crt_get_key_id(key, master_id); - if (ret < 0) - return gnutls_assert_val(ret); - if (memcmp(master_id, keyid, GNUTLS_OPENPGP_KEYID_SIZE) == 0) - return GNUTLS_OPENPGP_MASTER_KEYID_IDX; - - KEYID_IMPORT(kid, keyid); - ret = _gnutls_openpgp_find_subkey_idx(key->knode, kid, 0); - - if (ret < 0) { - gnutls_assert(); - } - - return ret; -} - -/** - * gnutls_openpgp_crt_get_subkey_usage: - * @key: should contain a gnutls_openpgp_crt_t type - * @idx: the subkey index - * @key_usage: where the key usage bits will be stored - * - * This function will return certificate's key usage, by checking the - * key algorithm. The key usage value will ORed values of - * %GNUTLS_KEY_DIGITAL_SIGNATURE or %GNUTLS_KEY_KEY_ENCIPHERMENT. - * - * A negative error code may be returned in case of parsing error. - * - * Returns: key usage value. - * - * Since: 2.4.0 - */ -int -gnutls_openpgp_crt_get_subkey_usage(gnutls_openpgp_crt_t key, - unsigned int idx, - unsigned int *key_usage) -{ - cdk_packet_t pkt; - - if (!key) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - return gnutls_openpgp_crt_get_key_usage(key, key_usage); - - pkt = _get_public_subkey(key, idx); - if (!pkt) - return GNUTLS_E_OPENPGP_SUBKEY_ERROR; - - *key_usage = - _gnutls_get_pgp_key_usage(pkt->pkt.public_key->pubkey_usage); - - return 0; -} - -int -_gnutls_read_pgp_mpi(cdk_packet_t pkt, unsigned int priv, size_t idx, - bigint_t * m) -{ - size_t buf_size = 512; - uint8_t *buf = gnutls_malloc(buf_size); - int err; - unsigned int max_pub_params = 0; - - if (priv != 0) - max_pub_params = - cdk_pk_get_npkey(pkt->pkt.secret_key->pk->pubkey_algo); - - if (buf == NULL) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - /* FIXME: Note that opencdk doesn't like the buf to be NULL. - */ - if (priv == 0) - err = - cdk_pk_get_mpi(pkt->pkt.public_key, idx, buf, buf_size, - &buf_size, NULL); - else { - if (idx < max_pub_params) - err = - cdk_pk_get_mpi(pkt->pkt.secret_key->pk, idx, - buf, buf_size, &buf_size, NULL); - else { - err = - cdk_sk_get_mpi(pkt->pkt.secret_key, - idx - max_pub_params, buf, - buf_size, &buf_size, NULL); - } - } - - if (err == CDK_Too_Short) { - buf = gnutls_realloc_fast(buf, buf_size); - if (buf == NULL) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - if (priv == 0) - err = - cdk_pk_get_mpi(pkt->pkt.public_key, idx, buf, - buf_size, &buf_size, NULL); - else { - if (idx < max_pub_params) - err = - cdk_pk_get_mpi(pkt->pkt.secret_key->pk, - idx, buf, buf_size, - &buf_size, NULL); - else { - err = - cdk_sk_get_mpi(pkt->pkt.secret_key, - idx - max_pub_params, - buf, buf_size, - &buf_size, NULL); - } - } - } - - if (err != CDK_Success) { - gnutls_assert(); - gnutls_free(buf); - return _gnutls_map_cdk_rc(err); - } - - err = _gnutls_mpi_init_scan(m, buf, buf_size); - gnutls_free(buf); - - if (err < 0) { - gnutls_assert(); - return err; - } - - return 0; -} - - -/* Extracts DSA and RSA parameters from a certificate. - */ -int -_gnutls_openpgp_crt_get_mpis(gnutls_openpgp_crt_t cert, - uint32_t * keyid /* [2] */ , - gnutls_pk_params_st * params) -{ - int result, i; - int pk_algorithm, local_params; - cdk_packet_t pkt; - - if (keyid == NULL) - pkt = - cdk_kbnode_find_packet(cert->knode, - CDK_PKT_PUBLIC_KEY); - else - pkt = _gnutls_openpgp_find_key(cert->knode, keyid, 0); - - if (pkt == NULL) { - gnutls_assert(); - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - } - - pk_algorithm = - _gnutls_openpgp_get_algo(pkt->pkt.public_key->pubkey_algo); - - switch (pk_algorithm) { - case GNUTLS_PK_RSA: - local_params = RSA_PUBLIC_PARAMS; - break; - case GNUTLS_PK_DSA: - local_params = DSA_PUBLIC_PARAMS; - break; - default: - gnutls_assert(); - return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE; - } - - gnutls_pk_params_init(params); - - for (i = 0; i < local_params; i++) { - result = - _gnutls_read_pgp_mpi(pkt, 0, i, ¶ms->params[i]); - if (result < 0) { - gnutls_assert(); - goto error; - } - params->params_nr++; - } - - return 0; - - error: - gnutls_pk_params_release(params); - - return result; -} - -/* The internal version of export - */ -static int -_get_pk_rsa_raw(gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid, - gnutls_datum_t * m, gnutls_datum_t * e) -{ - int pk_algorithm, ret; - cdk_packet_t pkt; - uint32_t kid32[2]; - gnutls_pk_params_st params; - - gnutls_pk_params_init(¶ms); - - if (crt == NULL) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - KEYID_IMPORT(kid32, keyid); - - pkt = _gnutls_openpgp_find_key(crt->knode, kid32, 0); - if (pkt == NULL) { - gnutls_assert(); - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - } - - pk_algorithm = - _gnutls_openpgp_get_algo(pkt->pkt.public_key->pubkey_algo); - - if (pk_algorithm != GNUTLS_PK_RSA) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - ret = _gnutls_openpgp_crt_get_mpis(crt, kid32, ¶ms); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - ret = _gnutls_mpi_dprint(params.params[0], m); - if (ret < 0) { - gnutls_assert(); - goto cleanup; - } - - ret = _gnutls_mpi_dprint(params.params[1], e); - if (ret < 0) { - gnutls_assert(); - _gnutls_free_datum(m); - goto cleanup; - } - - ret = 0; - - cleanup: - gnutls_pk_params_release(¶ms); - return ret; -} - -static int -_get_pk_dsa_raw(gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid, - gnutls_datum_t * p, gnutls_datum_t * q, - gnutls_datum_t * g, gnutls_datum_t * y) -{ - int pk_algorithm, ret; - cdk_packet_t pkt; - uint32_t kid32[2]; - gnutls_pk_params_st params; - - gnutls_pk_params_init(¶ms); - - if (crt == NULL) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - KEYID_IMPORT(kid32, keyid); - - pkt = _gnutls_openpgp_find_key(crt->knode, kid32, 0); - if (pkt == NULL) { - gnutls_assert(); - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - } - - pk_algorithm = - _gnutls_openpgp_get_algo(pkt->pkt.public_key->pubkey_algo); - - if (pk_algorithm != GNUTLS_PK_DSA) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - ret = _gnutls_openpgp_crt_get_mpis(crt, kid32, ¶ms); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - /* P */ - ret = _gnutls_mpi_dprint(params.params[0], p); - if (ret < 0) { - gnutls_assert(); - goto cleanup; - } - - /* Q */ - ret = _gnutls_mpi_dprint(params.params[1], q); - if (ret < 0) { - gnutls_assert(); - _gnutls_free_datum(p); - goto cleanup; - } - - - /* G */ - ret = _gnutls_mpi_dprint(params.params[2], g); - if (ret < 0) { - gnutls_assert(); - _gnutls_free_datum(p); - _gnutls_free_datum(q); - goto cleanup; - } - - - /* Y */ - ret = _gnutls_mpi_dprint(params.params[3], y); - if (ret < 0) { - gnutls_assert(); - _gnutls_free_datum(p); - _gnutls_free_datum(g); - _gnutls_free_datum(q); - goto cleanup; - } - - ret = 0; - - cleanup: - gnutls_pk_params_release(¶ms); - return ret; -} - - -/** - * gnutls_openpgp_crt_get_pk_rsa_raw: - * @crt: Holds the certificate - * @m: will hold the modulus - * @e: will hold the public exponent - * - * This function will export the RSA public key's parameters found in - * the given structure. The new parameters will be allocated using - * gnutls_malloc() and will be stored in the appropriate datum. - * - * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. - * - * Since: 2.4.0 - **/ -int -gnutls_openpgp_crt_get_pk_rsa_raw(gnutls_openpgp_crt_t crt, - gnutls_datum_t * m, gnutls_datum_t * e) -{ - uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; - int ret; - - ret = gnutls_openpgp_crt_get_key_id(crt, keyid); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - return _get_pk_rsa_raw(crt, keyid, m, e); -} - -/** - * gnutls_openpgp_crt_get_pk_dsa_raw: - * @crt: Holds the certificate - * @p: will hold the p - * @q: will hold the q - * @g: will hold the g - * @y: will hold the y - * - * This function will export the DSA public key's parameters found in - * the given certificate. The new parameters will be allocated using - * gnutls_malloc() and will be stored in the appropriate datum. - * - * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. - * - * Since: 2.4.0 - **/ -int -gnutls_openpgp_crt_get_pk_dsa_raw(gnutls_openpgp_crt_t crt, - gnutls_datum_t * p, gnutls_datum_t * q, - gnutls_datum_t * g, gnutls_datum_t * y) -{ - uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; - int ret; - - ret = gnutls_openpgp_crt_get_key_id(crt, keyid); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - return _get_pk_dsa_raw(crt, keyid, p, q, g, y); -} - -/** - * gnutls_openpgp_crt_get_subkey_pk_rsa_raw: - * @crt: Holds the certificate - * @idx: Is the subkey index - * @m: will hold the modulus - * @e: will hold the public exponent - * - * This function will export the RSA public key's parameters found in - * the given structure. The new parameters will be allocated using - * gnutls_malloc() and will be stored in the appropriate datum. - * - * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. - * - * Since: 2.4.0 - **/ -int -gnutls_openpgp_crt_get_subkey_pk_rsa_raw(gnutls_openpgp_crt_t crt, - unsigned int idx, - gnutls_datum_t * m, - gnutls_datum_t * e) -{ - uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; - int ret; - - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - return gnutls_openpgp_crt_get_pk_rsa_raw(crt, m, e); - - ret = gnutls_openpgp_crt_get_subkey_id(crt, idx, keyid); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - return _get_pk_rsa_raw(crt, keyid, m, e); -} - -/** - * gnutls_openpgp_crt_get_subkey_pk_dsa_raw: - * @crt: Holds the certificate - * @idx: Is the subkey index - * @p: will hold the p - * @q: will hold the q - * @g: will hold the g - * @y: will hold the y - * - * This function will export the DSA public key's parameters found in - * the given certificate. The new parameters will be allocated using - * gnutls_malloc() and will be stored in the appropriate datum. - * - * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. - * - * Since: 2.4.0 - **/ -int -gnutls_openpgp_crt_get_subkey_pk_dsa_raw(gnutls_openpgp_crt_t crt, - unsigned int idx, - gnutls_datum_t * p, - gnutls_datum_t * q, - gnutls_datum_t * g, - gnutls_datum_t * y) -{ - uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; - int ret; - - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - return gnutls_openpgp_crt_get_pk_dsa_raw(crt, p, q, g, y); - - ret = gnutls_openpgp_crt_get_subkey_id(crt, idx, keyid); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - return _get_pk_dsa_raw(crt, keyid, p, q, g, y); -} - -/** - * gnutls_openpgp_crt_get_preferred_key_id: - * @key: the structure that contains the OpenPGP public key. - * @keyid: the struct to save the keyid. - * - * Get preferred key id. If it hasn't been set it returns - * %GNUTLS_E_INVALID_REQUEST. - * - * Returns: the 64-bit preferred keyID of the OpenPGP key. - **/ -int -gnutls_openpgp_crt_get_preferred_key_id(gnutls_openpgp_crt_t key, - gnutls_openpgp_keyid_t keyid) -{ - if (!key || !keyid) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - if (!key->preferred_set) - return - gnutls_assert_val - (GNUTLS_E_OPENPGP_PREFERRED_KEY_ERROR); - - memcpy(keyid, key->preferred_keyid, GNUTLS_OPENPGP_KEYID_SIZE); - - return 0; -} - -/** - * gnutls_openpgp_crt_set_preferred_key_id: - * @key: the structure that contains the OpenPGP public key. - * @keyid: the selected keyid - * - * This allows setting a preferred key id for the given certificate. - * This key will be used by functions that involve key handling. - * - * If the provided @keyid is %NULL then the master key is - * set as preferred. - * - * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, - * otherwise a negative error code is returned. - **/ -int -gnutls_openpgp_crt_set_preferred_key_id(gnutls_openpgp_crt_t key, - const gnutls_openpgp_keyid_t keyid) -{ - int ret; - - if (!key) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - if (keyid == NULL) { /* set the master as preferred */ - uint8_t tmp[GNUTLS_OPENPGP_KEYID_SIZE]; - - ret = gnutls_openpgp_crt_get_key_id(key, tmp); - if (ret < 0) - return gnutls_assert_val(ret); - - key->preferred_set = 1; - memcpy(key->preferred_keyid, tmp, - GNUTLS_OPENPGP_KEYID_SIZE); - - return 0; - } - - /* check if the id is valid */ - ret = gnutls_openpgp_crt_get_subkey_idx(key, keyid); - if (ret < 0) { - _gnutls_debug_log("the requested subkey does not exist\n"); - gnutls_assert(); - return ret; - } - - key->preferred_set = 1; - memcpy(key->preferred_keyid, keyid, GNUTLS_OPENPGP_KEYID_SIZE); - - return 0; -} - -/** - * gnutls_openpgp_crt_get_auth_subkey: - * @crt: the structure that contains the OpenPGP public key. - * @keyid: the struct to save the keyid. - * @flag: Non-zero indicates that a valid subkey is always returned. - * - * Returns the 64-bit keyID of the first valid OpenPGP subkey marked - * for authentication. If flag is non-zero and no authentication - * subkey exists, then a valid subkey will be returned even if it is - * not marked for authentication. - * - * Returns: %GNUTLS_E_SUCCESS on success, or an error code. - **/ -int -gnutls_openpgp_crt_get_auth_subkey(gnutls_openpgp_crt_t crt, - gnutls_openpgp_keyid_t keyid, - unsigned int flag) -{ - int ret, subkeys, i; - unsigned int usage; - unsigned int keyid_init = 0; - - subkeys = gnutls_openpgp_crt_get_subkey_count(crt); - if (subkeys <= 0) { - gnutls_assert(); - return GNUTLS_E_OPENPGP_SUBKEY_ERROR; - } - - /* Try to find a subkey with the authentication flag set. - * if none exists use the last one found - */ - for (i = 0; i < subkeys; i++) { - ret = - gnutls_openpgp_crt_get_subkey_pk_algorithm(crt, i, - NULL); - if (ret == GNUTLS_PK_UNKNOWN) - continue; - - ret = gnutls_openpgp_crt_get_subkey_revoked_status(crt, i); - if (ret != 0) /* it is revoked. ignore it */ - continue; - - if (keyid_init == 0) { /* keep the first valid subkey */ - ret = - gnutls_openpgp_crt_get_subkey_id(crt, i, - keyid); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - keyid_init = 1; - } - - ret = gnutls_openpgp_crt_get_subkey_usage(crt, i, &usage); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - if (usage & GNUTLS_KEY_KEY_AGREEMENT) { - ret = - gnutls_openpgp_crt_get_subkey_id(crt, i, - keyid); - if (ret < 0) { - gnutls_assert(); - return ret; - } - return 0; - } - } - - if (flag && keyid_init) - return 0; - else - return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; -} diff --git a/lib/openpgp/pgpverify.c b/lib/openpgp/pgpverify.c deleted file mode 100644 index f9083507d8..0000000000 --- a/lib/openpgp/pgpverify.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2002-2010, 2012 Free Software Foundation, Inc. - * - * Author: Timo Schulz, Nikos Mavrogiannopoulos - * - * This file is part of GnuTLS. - * - * The GnuTLS 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -/* Functions on OpenPGP key parsing - */ - -#include "gnutls_int.h" -#include <openpgp_int.h> -#include "errors.h" -#include <openpgp.h> -#include <num.h> - -/** - * gnutls_openpgp_crt_verify_ring: - * @key: the structure that holds the key. - * @keyring: holds the keyring to check against - * @flags: unused (should be 0) - * @verify: will hold the certificate verification output. - * - * Verify all signatures in the key, using the given set of keys - * (keyring). - * - * The key verification output will be put in @verify and will be one - * or more of the #gnutls_certificate_status_t enumerated elements - * bitwise or'd. - * - * Note that this function does not verify using any "web of trust". - * You may use GnuPG for that purpose, or any other external PGP - * application. - * - * Returns: %GNUTLS_E_SUCCESS on success, or an error code. - **/ -int -gnutls_openpgp_crt_verify_ring(gnutls_openpgp_crt_t key, - gnutls_openpgp_keyring_t keyring, - unsigned int flags, unsigned int *verify) -{ - uint8_t id[GNUTLS_OPENPGP_KEYID_SIZE]; - cdk_error_t rc; - int status; - - if (!key || !keyring) { - gnutls_assert(); - return GNUTLS_E_NO_CERTIFICATE_FOUND; - } - - *verify = 0; - - rc = cdk_pk_check_sigs(key->knode, keyring->db, &status); - if (rc == CDK_Error_No_Key) { - rc = GNUTLS_E_NO_CERTIFICATE_FOUND; - gnutls_assert(); - return rc; - } else if (rc != CDK_Success) { - _gnutls_debug_log("cdk_pk_check_sigs: error %d\n", rc); - rc = _gnutls_map_cdk_rc(rc); - gnutls_assert(); - return rc; - } - _gnutls_debug_log("status: %x\n", status); - - if (status & CDK_KEY_INVALID) - *verify |= GNUTLS_CERT_SIGNATURE_FAILURE; - if (status & CDK_KEY_REVOKED) - *verify |= GNUTLS_CERT_REVOKED; - if (status & CDK_KEY_NOSIGNER) - *verify |= GNUTLS_CERT_SIGNER_NOT_FOUND; - - /* Check if the key is included in the ring. */ - if (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_SAME)) { - rc = gnutls_openpgp_crt_get_key_id(key, id); - if (rc < 0) { - gnutls_assert(); - return rc; - } - - rc = gnutls_openpgp_keyring_check_id(keyring, id, 0); - /* If it exists in the keyring don't treat it as unknown. */ - if (rc == 0 && *verify & GNUTLS_CERT_SIGNER_NOT_FOUND) - *verify &= ~GNUTLS_CERT_SIGNER_NOT_FOUND; - } - - if (*verify != 0) - *verify |= GNUTLS_CERT_INVALID; - - return 0; -} - - -/** - * gnutls_openpgp_crt_verify_self: - * @key: the structure that holds the key. - * @flags: unused (should be 0) - * @verify: will hold the key verification output. - * - * Verifies the self signature in the key. The key verification - * output will be put in @verify and will be one or more of the - * gnutls_certificate_status_t enumerated elements bitwise or'd. - * - * Returns: %GNUTLS_E_SUCCESS on success, or an error code. - **/ -int -gnutls_openpgp_crt_verify_self(gnutls_openpgp_crt_t key, - unsigned int flags, unsigned int *verify) -{ - int status; - cdk_error_t rc; - - *verify = 0; - - rc = cdk_pk_check_self_sig(key->knode, &status); - if (rc || status != CDK_KEY_VALID) - *verify |= - GNUTLS_CERT_INVALID | GNUTLS_CERT_SIGNATURE_FAILURE; - else - *verify = 0; - - return 0; -} diff --git a/lib/openpgp/privkey.c b/lib/openpgp/privkey.c deleted file mode 100644 index 6e88a3c5fb..0000000000 --- a/lib/openpgp/privkey.c +++ /dev/null @@ -1,1446 +0,0 @@ -/* - * Copyright (C) 2003-2012 Free Software Foundation, Inc. - * - * Author: Nikos Mavrogiannopoulos - * - * This file is part of GnuTLS. - * - * The GnuTLS 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 program. If not, see <http://www.gnu.org/licenses/> - * - */ - -/* Functions on OpenPGP privkey parsing - */ - -#include "gnutls_int.h" -#include <datum.h> -#include <global.h> -#include "errors.h" -#include <num.h> -#include <openpgp_int.h> -#include <openpgp.h> -#include <tls-sig.h> -#include <pk.h> - -/** - * gnutls_openpgp_privkey_init: - * @key: A pointer to the type to be initialized - * - * This function will initialize an OpenPGP key structure. - * - * Returns: %GNUTLS_E_SUCCESS on success, or an error code. - **/ -int gnutls_openpgp_privkey_init(gnutls_openpgp_privkey_t * key) -{ - *key = gnutls_calloc(1, sizeof(gnutls_openpgp_privkey_int)); - - if (*key) - return 0; /* success */ - return GNUTLS_E_MEMORY_ERROR; -} - -/** - * gnutls_openpgp_privkey_deinit: - * @key: A pointer to the type to be initialized - * - * This function will deinitialize a key structure. - **/ -void gnutls_openpgp_privkey_deinit(gnutls_openpgp_privkey_t key) -{ - if (!key) - return; - - if (key->knode) { - cdk_kbnode_release(key->knode); - key->knode = NULL; - } - - gnutls_free(key); -} - -/*- - * _gnutls_openpgp_privkey_cpy - This function copies a gnutls_openpgp_privkey_t type - * @dest: The structure where to copy - * @src: The structure to be copied - * - * This function will copy an X.509 certificate structure. - * - * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a - * negative error value. - -*/ -int -_gnutls_openpgp_privkey_cpy(gnutls_openpgp_privkey_t dest, - gnutls_openpgp_privkey_t src) -{ - int ret; - size_t raw_size = 0; - uint8_t *der; - gnutls_datum_t tmp; - - ret = - gnutls_openpgp_privkey_export(src, GNUTLS_OPENPGP_FMT_RAW, - NULL, 0, NULL, &raw_size); - if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER) - return gnutls_assert_val(ret); - - der = gnutls_malloc(raw_size); - if (der == NULL) - return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); - - ret = - gnutls_openpgp_privkey_export(src, GNUTLS_OPENPGP_FMT_RAW, - NULL, 0, der, &raw_size); - if (ret < 0) { - gnutls_assert(); - gnutls_free(der); - return ret; - } - - tmp.data = der; - tmp.size = raw_size; - ret = - gnutls_openpgp_privkey_import(dest, &tmp, - GNUTLS_OPENPGP_FMT_RAW, NULL, 0); - - gnutls_free(der); - - if (ret < 0) - return gnutls_assert_val(ret); - - memcpy(dest->preferred_keyid, src->preferred_keyid, - GNUTLS_OPENPGP_KEYID_SIZE); - dest->preferred_set = src->preferred_set; - - return 0; -} - -/** - * gnutls_openpgp_privkey_sec_param: - * @key: a key structure - * - * This function will return the security parameter appropriate with - * this private key. - * - * Returns: On success, a valid security parameter is returned otherwise - * %GNUTLS_SEC_PARAM_UNKNOWN is returned. - * - * Since: 2.12.0 - **/ -gnutls_sec_param_t -gnutls_openpgp_privkey_sec_param(gnutls_openpgp_privkey_t key) -{ - gnutls_pk_algorithm_t algo; - unsigned int bits; - - algo = gnutls_openpgp_privkey_get_pk_algorithm(key, &bits); - if (algo == GNUTLS_PK_UNKNOWN) { - gnutls_assert(); - return GNUTLS_SEC_PARAM_UNKNOWN; - } - - return gnutls_pk_bits_to_sec_param(algo, bits); -} - -/** - * gnutls_openpgp_privkey_import: - * @key: The structure to store the parsed key. - * @data: The RAW or BASE64 encoded key. - * @format: One of #gnutls_openpgp_crt_fmt_t elements. - * @password: not used for now - * @flags: should be (0) - * - * This function will convert the given RAW or Base64 encoded key to - * the native gnutls_openpgp_privkey_t format. The output will be - * stored in 'key'. - * - * Returns: %GNUTLS_E_SUCCESS on success, or an error code. - **/ -int -gnutls_openpgp_privkey_import(gnutls_openpgp_privkey_t key, - const gnutls_datum_t * data, - gnutls_openpgp_crt_fmt_t format, - const char *password, unsigned int flags) -{ - cdk_packet_t pkt; - int rc, armor; - - if (data->data == NULL || data->size == 0) { - gnutls_assert(); - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - } - - if (format == GNUTLS_OPENPGP_FMT_RAW) - armor = 0; - else - armor = 1; - - rc = cdk_kbnode_read_from_mem(&key->knode, armor, data->data, - data->size, 0); - if (rc != 0) { - rc = _gnutls_map_cdk_rc(rc); - gnutls_assert(); - return rc; - } - - /* Test if the import was successful. */ - pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_SECRET_KEY); - if (pkt == NULL) { - gnutls_assert(); - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - } - - return 0; -} - -/** - * gnutls_openpgp_privkey_export: - * @key: Holds the key. - * @format: One of gnutls_openpgp_crt_fmt_t elements. - * @password: the password that will be used to encrypt the key. (unused for now) - * @flags: (0) for future compatibility - * @output_data: will contain the key base64 encoded or raw - * @output_data_size: holds the size of output_data (and will be - * replaced by the actual size of parameters) - * - * This function will convert the given key to RAW or Base64 format. - * If the buffer provided is not long enough to hold the output, then - * GNUTLS_E_SHORT_MEMORY_BUFFER will be returned. - * - * Returns: %GNUTLS_E_SUCCESS on success, or an error code. - * - * Since: 2.4.0 - **/ -int -gnutls_openpgp_privkey_export(gnutls_openpgp_privkey_t key, - gnutls_openpgp_crt_fmt_t format, - const char *password, unsigned int flags, - void *output_data, size_t * output_data_size) -{ - /* FIXME for now we do not export encrypted keys */ - return _gnutls_openpgp_export(key->knode, format, output_data, - output_data_size, 1); -} - -/** - * gnutls_openpgp_privkey_export2: - * @key: Holds the key. - * @format: One of gnutls_openpgp_crt_fmt_t elements. - * @password: the password that will be used to encrypt the key. (unused for now) - * @flags: (0) for future compatibility - * @out: will contain the raw or based64 encoded key - * - * This function will convert the given key to RAW or Base64 format. - * The output buffer is allocated using gnutls_malloc(). - * - * Returns: %GNUTLS_E_SUCCESS on success, or an error code. - * - * Since: 3.1.3 - **/ -int -gnutls_openpgp_privkey_export2(gnutls_openpgp_privkey_t key, - gnutls_openpgp_crt_fmt_t format, - const char *password, unsigned int flags, - gnutls_datum_t * out) -{ - /* FIXME for now we do not export encrypted keys */ - return _gnutls_openpgp_export2(key->knode, format, out, 1); -} - - -/** - * gnutls_openpgp_privkey_get_pk_algorithm: - * @key: is an OpenPGP key - * @bits: if bits is non null it will hold the size of the parameters' in bits - * - * This function will return the public key algorithm of an OpenPGP - * certificate. - * - * If bits is non null, it should have enough size to hold the parameters - * size in bits. For RSA the bits returned is the modulus. - * For DSA the bits returned are of the public exponent. - * - * Returns: a member of the #gnutls_pk_algorithm_t enumeration on - * success, or a negative error code on error. - * - * Since: 2.4.0 - **/ -gnutls_pk_algorithm_t -gnutls_openpgp_privkey_get_pk_algorithm(gnutls_openpgp_privkey_t key, - unsigned int *bits) -{ - cdk_packet_t pkt; - int algo = 0, ret; - uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; - - if (!key) { - gnutls_assert(); - return GNUTLS_PK_UNKNOWN; - } - - ret = gnutls_openpgp_privkey_get_preferred_key_id(key, keyid); - if (ret == 0) { - int idx; - - idx = gnutls_openpgp_privkey_get_subkey_idx(key, keyid); - if (idx != GNUTLS_OPENPGP_MASTER_KEYID_IDX) { - algo = - gnutls_openpgp_privkey_get_subkey_pk_algorithm - (key, idx, bits); - return algo; - } - } - - pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_SECRET_KEY); - if (pkt) { - if (bits) - *bits = cdk_pk_get_nbits(pkt->pkt.secret_key->pk); - algo = - _gnutls_openpgp_get_algo(pkt->pkt.secret_key->pk-> - pubkey_algo); - } - - return algo; -} - -int _gnutls_openpgp_get_algo(int cdk_algo) -{ - int algo; - - if (is_RSA(cdk_algo)) - algo = GNUTLS_PK_RSA; - else if (is_DSA(cdk_algo)) - algo = GNUTLS_PK_DSA; - else { - _gnutls_debug_log("Unknown OpenPGP algorithm %d\n", - cdk_algo); - algo = GNUTLS_PK_UNKNOWN; - } - - return algo; -} - -/** - * gnutls_openpgp_privkey_get_revoked_status: - * @key: the structure that contains the OpenPGP private key. - * - * Get revocation status of key. - * - * Returns: true (1) if the key has been revoked, or false (0) if it - * has not, or a negative error code indicates an error. - * - * Since: 2.4.0 - **/ -int gnutls_openpgp_privkey_get_revoked_status(gnutls_openpgp_privkey_t key) -{ - cdk_packet_t pkt; - - if (!key) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_SECRET_KEY); - if (!pkt) - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - - if (pkt->pkt.secret_key->is_revoked != 0) - return 1; - return 0; -} - -/** - * gnutls_openpgp_privkey_get_fingerprint: - * @key: the raw data that contains the OpenPGP secret key. - * @fpr: the buffer to save the fingerprint, must hold at least 20 bytes. - * @fprlen: the integer to save the length of the fingerprint. - * - * Get the fingerprint of the OpenPGP key. Depends on the - * algorithm, the fingerprint can be 16 or 20 bytes. - * - * Returns: On success, 0 is returned, or an error code. - * - * Since: 2.4.0 - **/ -int -gnutls_openpgp_privkey_get_fingerprint(gnutls_openpgp_privkey_t key, - void *fpr, size_t * fprlen) -{ - cdk_packet_t pkt; - cdk_pkt_pubkey_t pk = NULL; - - if (!fpr || !fprlen) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - *fprlen = 0; - - pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_SECRET_KEY); - if (!pkt) { - gnutls_assert(); - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - } - - pk = pkt->pkt.secret_key->pk; - *fprlen = 20; - - if (is_RSA(pk->pubkey_algo) && pk->version < 4) - *fprlen = 16; - - cdk_pk_get_fingerprint(pk, fpr); - - return 0; -} - -/** - * gnutls_openpgp_privkey_get_key_id: - * @key: the structure that contains the OpenPGP secret key. - * @keyid: the buffer to save the keyid. - * - * Get key-id. - * - * Returns: the 64-bit keyID of the OpenPGP key. - * - * Since: 2.4.0 - **/ -int -gnutls_openpgp_privkey_get_key_id(gnutls_openpgp_privkey_t key, - gnutls_openpgp_keyid_t keyid) -{ - cdk_packet_t pkt; - uint32_t kid[2]; - - if (!key || !keyid) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_SECRET_KEY); - if (!pkt) - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - - cdk_sk_get_keyid(pkt->pkt.secret_key, kid); - _gnutls_write_uint32(kid[0], keyid); - _gnutls_write_uint32(kid[1], keyid + 4); - - return 0; -} - -/** - * gnutls_openpgp_privkey_get_subkey_count: - * @key: is an OpenPGP key - * - * This function will return the number of subkeys present in the - * given OpenPGP certificate. - * - * Returns: the number of subkeys, or a negative error code on error. - * - * Since: 2.4.0 - **/ -int gnutls_openpgp_privkey_get_subkey_count(gnutls_openpgp_privkey_t key) -{ - cdk_kbnode_t p, ctx; - cdk_packet_t pkt; - int subkeys; - - if (key == NULL) { - gnutls_assert(); - return 0; - } - - ctx = NULL; - subkeys = 0; - while ((p = cdk_kbnode_walk(key->knode, &ctx, 0))) { - pkt = cdk_kbnode_get_packet(p); - if (pkt->pkttype == CDK_PKT_SECRET_SUBKEY) - subkeys++; - } - - return subkeys; -} - -/* returns the subkey with the given index */ -static cdk_packet_t -_get_secret_subkey(gnutls_openpgp_privkey_t key, unsigned int indx) -{ - cdk_kbnode_t p, ctx; - cdk_packet_t pkt; - unsigned int subkeys; - - ctx = NULL; - subkeys = 0; - while ((p = cdk_kbnode_walk(key->knode, &ctx, 0))) { - pkt = cdk_kbnode_get_packet(p); - if (pkt->pkttype == CDK_PKT_SECRET_SUBKEY - && indx == subkeys++) - return pkt; - } - - return NULL; -} - -/** - * gnutls_openpgp_privkey_get_subkey_revoked_status: - * @key: the structure that contains the OpenPGP private key. - * @idx: is the subkey index - * - * Get revocation status of key. - * - * Returns: true (1) if the key has been revoked, or false (0) if it - * has not, or a negative error code indicates an error. - * - * Since: 2.4.0 - **/ -int -gnutls_openpgp_privkey_get_subkey_revoked_status(gnutls_openpgp_privkey_t - key, unsigned int idx) -{ - cdk_packet_t pkt; - - if (!key) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - return gnutls_openpgp_privkey_get_revoked_status(key); - - pkt = _get_secret_subkey(key, idx); - if (!pkt) - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - - if (pkt->pkt.secret_key->is_revoked != 0) - return 1; - return 0; -} - -/** - * gnutls_openpgp_privkey_get_subkey_pk_algorithm: - * @key: is an OpenPGP key - * @idx: is the subkey index - * @bits: if bits is non null it will hold the size of the parameters' in bits - * - * This function will return the public key algorithm of a subkey of an OpenPGP - * certificate. - * - * If bits is non null, it should have enough size to hold the parameters - * size in bits. For RSA the bits returned is the modulus. - * For DSA the bits returned are of the public exponent. - * - * Returns: a member of the #gnutls_pk_algorithm_t enumeration on - * success, or a negative error code on error. - * - * Since: 2.4.0 - **/ -gnutls_pk_algorithm_t -gnutls_openpgp_privkey_get_subkey_pk_algorithm(gnutls_openpgp_privkey_t - key, unsigned int idx, - unsigned int *bits) -{ - cdk_packet_t pkt; - int algo; - - if (!key) { - gnutls_assert(); - return GNUTLS_PK_UNKNOWN; - } - - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - return gnutls_openpgp_privkey_get_pk_algorithm(key, bits); - - pkt = _get_secret_subkey(key, idx); - - algo = 0; - if (pkt) { - if (bits) - *bits = cdk_pk_get_nbits(pkt->pkt.secret_key->pk); - algo = pkt->pkt.secret_key->pubkey_algo; - if (is_RSA(algo)) - algo = GNUTLS_PK_RSA; - else if (is_DSA(algo)) - algo = GNUTLS_PK_DSA; - else - algo = GNUTLS_E_UNKNOWN_PK_ALGORITHM; - } - - return algo; -} - -/** - * gnutls_openpgp_privkey_get_subkey_idx: - * @key: the structure that contains the OpenPGP private key. - * @keyid: the keyid. - * - * Get index of subkey. - * - * Returns: the index of the subkey or a negative error value. - * - * Since: 2.4.0 - **/ -int -gnutls_openpgp_privkey_get_subkey_idx(gnutls_openpgp_privkey_t key, - const gnutls_openpgp_keyid_t keyid) -{ - int ret; - uint32_t kid[2]; - uint8_t master_id[GNUTLS_OPENPGP_KEYID_SIZE]; - - if (!key) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - ret = gnutls_openpgp_privkey_get_key_id(key, master_id); - if (ret < 0) - return gnutls_assert_val(ret); - if (memcmp(master_id, keyid, GNUTLS_OPENPGP_KEYID_SIZE) == 0) - return GNUTLS_OPENPGP_MASTER_KEYID_IDX; - - KEYID_IMPORT(kid, keyid); - ret = _gnutls_openpgp_find_subkey_idx(key->knode, kid, 1); - - if (ret < 0) { - gnutls_assert(); - } - - return ret; -} - -/** - * gnutls_openpgp_privkey_get_subkey_creation_time: - * @key: the structure that contains the OpenPGP private key. - * @idx: the subkey index - * - * Get subkey creation time. - * - * Returns: the timestamp when the OpenPGP key was created. - * - * Since: 2.4.0 - **/ -time_t -gnutls_openpgp_privkey_get_subkey_creation_time(gnutls_openpgp_privkey_t - key, unsigned int idx) -{ - cdk_packet_t pkt; - time_t timestamp; - - if (!key) - return (time_t) - 1; - - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - pkt = - cdk_kbnode_find_packet(key->knode, CDK_PKT_SECRET_KEY); - else - pkt = _get_secret_subkey(key, idx); - - if (pkt) - timestamp = pkt->pkt.secret_key->pk->timestamp; - else - timestamp = 0; - - return timestamp; -} - -/** - * gnutls_openpgp_privkey_get_subkey_expiration_time: - * @key: the structure that contains the OpenPGP private key. - * @idx: the subkey index - * - * Get subkey expiration time. A value of '0' means that the key - * doesn't expire at all. - * - * Returns: the time when the OpenPGP key expires. - * - * Since: 2.4.0 - **/ -time_t -gnutls_openpgp_privkey_get_subkey_expiration_time(gnutls_openpgp_privkey_t - key, unsigned int idx) -{ - cdk_packet_t pkt; - time_t timestamp; - - if (!key) - return (time_t) - 1; - - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - pkt = - cdk_kbnode_find_packet(key->knode, CDK_PKT_SECRET_KEY); - else - pkt = _get_secret_subkey(key, idx); - - if (pkt) - timestamp = pkt->pkt.secret_key->pk->expiredate; - else - timestamp = 0; - - return timestamp; -} - -/** - * gnutls_openpgp_privkey_get_subkey_id: - * @key: the structure that contains the OpenPGP secret key. - * @idx: the subkey index - * @keyid: the buffer to save the keyid. - * - * Get the key-id for the subkey. - * - * Returns: the 64-bit keyID of the OpenPGP key. - * - * Since: 2.4.0 - **/ -int -gnutls_openpgp_privkey_get_subkey_id(gnutls_openpgp_privkey_t key, - unsigned int idx, - gnutls_openpgp_keyid_t keyid) -{ - cdk_packet_t pkt; - uint32_t kid[2]; - - if (!key || !keyid) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - return gnutls_openpgp_privkey_get_key_id(key, keyid); - - pkt = _get_secret_subkey(key, idx); - if (!pkt) - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - - cdk_sk_get_keyid(pkt->pkt.secret_key, kid); - _gnutls_write_uint32(kid[0], keyid); - _gnutls_write_uint32(kid[1], keyid + 4); - - return 0; -} - -/** - * gnutls_openpgp_privkey_get_subkey_fingerprint: - * @key: the raw data that contains the OpenPGP secret key. - * @idx: the subkey index - * @fpr: the buffer to save the fingerprint, must hold at least 20 bytes. - * @fprlen: the integer to save the length of the fingerprint. - * - * Get the fingerprint of an OpenPGP subkey. Depends on the - * algorithm, the fingerprint can be 16 or 20 bytes. - * - * Returns: On success, 0 is returned, or an error code. - * - * Since: 2.4.0 - **/ -int -gnutls_openpgp_privkey_get_subkey_fingerprint(gnutls_openpgp_privkey_t key, - unsigned int idx, - void *fpr, size_t * fprlen) -{ - cdk_packet_t pkt; - cdk_pkt_pubkey_t pk = NULL; - - if (!fpr || !fprlen) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - return gnutls_openpgp_privkey_get_fingerprint(key, fpr, - fprlen); - - *fprlen = 0; - - pkt = _get_secret_subkey(key, idx); - if (!pkt) - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - - - pk = pkt->pkt.secret_key->pk; - *fprlen = 20; - - if (is_RSA(pk->pubkey_algo) && pk->version < 4) - *fprlen = 16; - - cdk_pk_get_fingerprint(pk, fpr); - - return 0; -} - -/* Extracts DSA and RSA parameters from a certificate. - */ -int -_gnutls_openpgp_privkey_get_mpis(gnutls_openpgp_privkey_t pkey, - uint32_t * keyid /*[2] */ , - gnutls_pk_params_st * params) -{ - int result; - unsigned int i, pk_algorithm; - cdk_packet_t pkt; - unsigned total; - - gnutls_pk_params_init(params); - - if (keyid == NULL) - pkt = - cdk_kbnode_find_packet(pkey->knode, - CDK_PKT_SECRET_KEY); - else - pkt = _gnutls_openpgp_find_key(pkey->knode, keyid, 1); - - if (pkt == NULL) { - gnutls_assert(); - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - } - - pk_algorithm = - _gnutls_openpgp_get_algo(pkt->pkt.secret_key->pk->pubkey_algo); - params->algo = pk_algorithm; - - switch (pk_algorithm) { - case GNUTLS_PK_RSA: - /* openpgp does not hold all parameters as in PKCS #1 - */ - total = RSA_PRIVATE_PARAMS - 2; - break; - case GNUTLS_PK_DSA: - total = DSA_PRIVATE_PARAMS; - break; - default: - gnutls_assert(); - return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE; - } - - for (i = 0; i < total; i++) { - result = - _gnutls_read_pgp_mpi(pkt, 1, i, ¶ms->params[i]); - if (result < 0) { - gnutls_assert(); - goto error; - } - params->params_nr++; - } - - /* fixup will generate exp1 and exp2 that are not - * available here. - */ - result = _gnutls_pk_fixup(pk_algorithm, GNUTLS_IMPORT, params); - if (result < 0) { - gnutls_assert(); - goto error; - } - - return 0; - - error: - gnutls_pk_params_clear(params); - gnutls_pk_params_release(params); - - return result; -} - -/* The internal version of export - */ -static int -_get_sk_rsa_raw(gnutls_openpgp_privkey_t pkey, - gnutls_openpgp_keyid_t keyid, gnutls_datum_t * m, - gnutls_datum_t * e, gnutls_datum_t * d, gnutls_datum_t * p, - gnutls_datum_t * q, gnutls_datum_t * u) -{ - int pk_algorithm, ret; - cdk_packet_t pkt; - uint32_t kid32[2]; - gnutls_pk_params_st params; - - if (pkey == NULL) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - KEYID_IMPORT(kid32, keyid); - - pkt = _gnutls_openpgp_find_key(pkey->knode, kid32, 1); - if (pkt == NULL) { - gnutls_assert(); - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - } - - pk_algorithm = - _gnutls_openpgp_get_algo(pkt->pkt.secret_key->pk->pubkey_algo); - - if (pk_algorithm != GNUTLS_PK_RSA) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - ret = _gnutls_openpgp_privkey_get_mpis(pkey, kid32, ¶ms); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - ret = _gnutls_mpi_dprint(params.params[0], m); - if (ret < 0) { - gnutls_assert(); - goto cleanup; - } - - ret = _gnutls_mpi_dprint(params.params[1], e); - if (ret < 0) { - gnutls_assert(); - _gnutls_free_datum(m); - goto cleanup; - } - - ret = _gnutls_mpi_dprint(params.params[2], d); - if (ret < 0) { - gnutls_assert(); - _gnutls_free_datum(m); - _gnutls_free_datum(e); - goto cleanup; - } - - ret = _gnutls_mpi_dprint(params.params[3], p); - if (ret < 0) { - gnutls_assert(); - _gnutls_free_datum(m); - _gnutls_free_datum(e); - _gnutls_free_datum(d); - goto cleanup; - } - - ret = _gnutls_mpi_dprint(params.params[4], q); - if (ret < 0) { - gnutls_assert(); - _gnutls_free_datum(m); - _gnutls_free_datum(e); - _gnutls_free_datum(d); - _gnutls_free_datum(p); - goto cleanup; - } - - ret = _gnutls_mpi_dprint(params.params[5], u); - if (ret < 0) { - gnutls_assert(); - _gnutls_free_datum(q); - _gnutls_free_datum(m); - _gnutls_free_datum(e); - _gnutls_free_datum(d); - _gnutls_free_datum(p); - goto cleanup; - } - - ret = 0; - - cleanup: - gnutls_pk_params_clear(¶ms); - gnutls_pk_params_release(¶ms); - return ret; -} - -static int -_get_sk_dsa_raw(gnutls_openpgp_privkey_t pkey, - gnutls_openpgp_keyid_t keyid, gnutls_datum_t * p, - gnutls_datum_t * q, gnutls_datum_t * g, gnutls_datum_t * y, - gnutls_datum_t * x) -{ - int pk_algorithm, ret; - cdk_packet_t pkt; - uint32_t kid32[2]; - gnutls_pk_params_st params; - - if (pkey == NULL) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - KEYID_IMPORT(kid32, keyid); - - pkt = _gnutls_openpgp_find_key(pkey->knode, kid32, 1); - if (pkt == NULL) { - gnutls_assert(); - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - } - - pk_algorithm = - _gnutls_openpgp_get_algo(pkt->pkt.secret_key->pk->pubkey_algo); - - if (pk_algorithm != GNUTLS_PK_DSA) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - ret = _gnutls_openpgp_privkey_get_mpis(pkey, kid32, ¶ms); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - /* P */ - ret = _gnutls_mpi_dprint(params.params[0], p); - if (ret < 0) { - gnutls_assert(); - goto cleanup; - } - - /* Q */ - ret = _gnutls_mpi_dprint(params.params[1], q); - if (ret < 0) { - gnutls_assert(); - _gnutls_free_datum(p); - goto cleanup; - } - - - /* G */ - ret = _gnutls_mpi_dprint(params.params[2], g); - if (ret < 0) { - gnutls_assert(); - _gnutls_free_datum(p); - _gnutls_free_datum(q); - goto cleanup; - } - - - /* Y */ - ret = _gnutls_mpi_dprint(params.params[3], y); - if (ret < 0) { - gnutls_assert(); - _gnutls_free_datum(p); - _gnutls_free_datum(g); - _gnutls_free_datum(q); - goto cleanup; - } - - ret = _gnutls_mpi_dprint(params.params[4], x); - if (ret < 0) { - gnutls_assert(); - _gnutls_free_datum(y); - _gnutls_free_datum(p); - _gnutls_free_datum(g); - _gnutls_free_datum(q); - goto cleanup; - } - - ret = 0; - - cleanup: - gnutls_pk_params_clear(¶ms); - gnutls_pk_params_release(¶ms); - return ret; -} - - -/** - * gnutls_openpgp_privkey_export_rsa_raw: - * @pkey: Holds the certificate - * @m: will hold the modulus - * @e: will hold the public exponent - * @d: will hold the private exponent - * @p: will hold the first prime (p) - * @q: will hold the second prime (q) - * @u: will hold the coefficient - * - * This function will export the RSA private key's parameters found in - * the given structure. The new parameters will be allocated using - * gnutls_malloc() and will be stored in the appropriate datum. - * - * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. - * - * Since: 2.4.0 - **/ -int -gnutls_openpgp_privkey_export_rsa_raw(gnutls_openpgp_privkey_t pkey, - gnutls_datum_t * m, - gnutls_datum_t * e, - gnutls_datum_t * d, - gnutls_datum_t * p, - gnutls_datum_t * q, - gnutls_datum_t * u) -{ - uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; - int ret; - - ret = gnutls_openpgp_privkey_get_key_id(pkey, keyid); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - return _get_sk_rsa_raw(pkey, keyid, m, e, d, p, q, u); -} - -/** - * gnutls_openpgp_privkey_export_dsa_raw: - * @pkey: Holds the certificate - * @p: will hold the p - * @q: will hold the q - * @g: will hold the g - * @y: will hold the y - * @x: will hold the x - * - * This function will export the DSA private key's parameters found in - * the given certificate. The new parameters will be allocated using - * gnutls_malloc() and will be stored in the appropriate datum. - * - * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. - * - * Since: 2.4.0 - **/ -int -gnutls_openpgp_privkey_export_dsa_raw(gnutls_openpgp_privkey_t pkey, - gnutls_datum_t * p, - gnutls_datum_t * q, - gnutls_datum_t * g, - gnutls_datum_t * y, - gnutls_datum_t * x) -{ - uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; - int ret; - - ret = gnutls_openpgp_privkey_get_key_id(pkey, keyid); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - return _get_sk_dsa_raw(pkey, keyid, p, q, g, y, x); -} - -/** - * gnutls_openpgp_privkey_export_subkey_rsa_raw: - * @pkey: Holds the certificate - * @idx: Is the subkey index - * @m: will hold the modulus - * @e: will hold the public exponent - * @d: will hold the private exponent - * @p: will hold the first prime (p) - * @q: will hold the second prime (q) - * @u: will hold the coefficient - * - * This function will export the RSA private key's parameters found in - * the given structure. The new parameters will be allocated using - * gnutls_malloc() and will be stored in the appropriate datum. - * - * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. - * - * Since: 2.4.0 - **/ -int -gnutls_openpgp_privkey_export_subkey_rsa_raw(gnutls_openpgp_privkey_t pkey, - unsigned int idx, - gnutls_datum_t * m, - gnutls_datum_t * e, - gnutls_datum_t * d, - gnutls_datum_t * p, - gnutls_datum_t * q, - gnutls_datum_t * u) -{ - uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; - int ret; - - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - ret = gnutls_openpgp_privkey_get_key_id(pkey, keyid); - else - ret = - gnutls_openpgp_privkey_get_subkey_id(pkey, idx, keyid); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - return _get_sk_rsa_raw(pkey, keyid, m, e, d, p, q, u); -} - -/** - * gnutls_openpgp_privkey_export_subkey_dsa_raw: - * @pkey: Holds the certificate - * @idx: Is the subkey index - * @p: will hold the p - * @q: will hold the q - * @g: will hold the g - * @y: will hold the y - * @x: will hold the x - * - * This function will export the DSA private key's parameters found - * in the given certificate. The new parameters will be allocated - * using gnutls_malloc() and will be stored in the appropriate datum. - * - * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. - * - * Since: 2.4.0 - **/ -int -gnutls_openpgp_privkey_export_subkey_dsa_raw(gnutls_openpgp_privkey_t pkey, - unsigned int idx, - gnutls_datum_t * p, - gnutls_datum_t * q, - gnutls_datum_t * g, - gnutls_datum_t * y, - gnutls_datum_t * x) -{ - uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; - int ret; - - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - ret = gnutls_openpgp_privkey_get_key_id(pkey, keyid); - else - ret = - gnutls_openpgp_privkey_get_subkey_id(pkey, idx, keyid); - - if (ret < 0) { - gnutls_assert(); - return ret; - } - - return _get_sk_dsa_raw(pkey, keyid, p, q, g, y, x); -} - -/** - * gnutls_openpgp_privkey_get_preferred_key_id: - * @key: the structure that contains the OpenPGP public key. - * @keyid: the struct to save the keyid. - * - * Get the preferred key-id for the key. - * - * Returns: the 64-bit preferred keyID of the OpenPGP key, or if it - * hasn't been set it returns %GNUTLS_E_INVALID_REQUEST. - **/ -int -gnutls_openpgp_privkey_get_preferred_key_id(gnutls_openpgp_privkey_t key, - gnutls_openpgp_keyid_t keyid) -{ - if (!key || !keyid) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - if (!key->preferred_set) - return - gnutls_assert_val - (GNUTLS_E_OPENPGP_PREFERRED_KEY_ERROR); - - memcpy(keyid, key->preferred_keyid, GNUTLS_OPENPGP_KEYID_SIZE); - - return 0; -} - -/** - * gnutls_openpgp_privkey_set_preferred_key_id: - * @key: the structure that contains the OpenPGP public key. - * @keyid: the selected keyid - * - * This allows setting a preferred key id for the given certificate. - * This key will be used by functions that involve key handling. - * - * If the provided @keyid is %NULL then the master key is - * set as preferred. - * - * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, - * otherwise a negative error code is returned. - **/ -int -gnutls_openpgp_privkey_set_preferred_key_id(gnutls_openpgp_privkey_t key, - const gnutls_openpgp_keyid_t - keyid) -{ - int ret; - - if (!key) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - if (keyid == NULL) { /* set the master as preferred */ - uint8_t tmp[GNUTLS_OPENPGP_KEYID_SIZE]; - - ret = gnutls_openpgp_privkey_get_key_id(key, tmp); - if (ret < 0) - return gnutls_assert_val(ret); - - key->preferred_set = 1; - memcpy(key->preferred_keyid, tmp, - GNUTLS_OPENPGP_KEYID_SIZE); - - return 0; - } - - /* check if the id is valid */ - ret = gnutls_openpgp_privkey_get_subkey_idx(key, keyid); - if (ret < 0) { - _gnutls_debug_log("the requested subkey does not exist\n"); - gnutls_assert(); - return ret; - } - - key->preferred_set = 1; - memcpy(key->preferred_keyid, keyid, GNUTLS_OPENPGP_KEYID_SIZE); - - return 0; -} - -/** - * gnutls_openpgp_privkey_sign_hash: - * @key: Holds the key - * @hash: holds the data to be signed - * @signature: will contain newly allocated signature - * - * This function will sign the given hash using the private key. You - * should use gnutls_openpgp_privkey_set_preferred_key_id() before - * calling this function to set the subkey to use. - * - * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a - * negative error value. - * - * Deprecated: Use gnutls_privkey_sign_hash() instead. - */ -int -gnutls_openpgp_privkey_sign_hash(gnutls_openpgp_privkey_t key, - const gnutls_datum_t * hash, - gnutls_datum_t * signature) -{ - int result; - gnutls_pk_params_st params; - int pk_algorithm; - uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; - char buf[2 * GNUTLS_OPENPGP_KEYID_SIZE + 1]; - - if (key == NULL) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - result = gnutls_openpgp_privkey_get_preferred_key_id(key, keyid); - if (result == 0) { - uint32_t kid[2]; - int idx; - - KEYID_IMPORT(kid, keyid); - - _gnutls_hard_log("Signing using PGP key ID %s\n", - _gnutls_bin2hex(keyid, - GNUTLS_OPENPGP_KEYID_SIZE, - buf, sizeof(buf), NULL)); - - idx = gnutls_openpgp_privkey_get_subkey_idx(key, keyid); - pk_algorithm = - gnutls_openpgp_privkey_get_subkey_pk_algorithm(key, - idx, - NULL); - result = - _gnutls_openpgp_privkey_get_mpis(key, kid, ¶ms); - } else { - _gnutls_hard_log("Signing using master PGP key\n"); - - pk_algorithm = - gnutls_openpgp_privkey_get_pk_algorithm(key, NULL); - result = - _gnutls_openpgp_privkey_get_mpis(key, NULL, ¶ms); - } - - if (result < 0) { - gnutls_assert(); - return result; - } - - - result = _gnutls_pk_sign(pk_algorithm, signature, hash, ¶ms, ¶ms.sign); - - gnutls_pk_params_clear(¶ms); - gnutls_pk_params_release(¶ms); - - if (result < 0) { - gnutls_assert(); - return result; - } - - return 0; -} - -/*- - * _gnutls_openpgp_privkey_decrypt_data: - * @key: Holds the key - * @flags: (0) for now - * @ciphertext: holds the data to be decrypted - * @plaintext: will contain newly allocated plaintext - * - * This function will sign the given hash using the private key. You - * should use gnutls_openpgp_privkey_set_preferred_key_id() before - * calling this function to set the subkey to use. - * - * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a - * negative error value. - -*/ -int -_gnutls_openpgp_privkey_decrypt_data(gnutls_openpgp_privkey_t key, - unsigned int flags, - const gnutls_datum_t * ciphertext, - gnutls_datum_t * plaintext) -{ - int result, i; - gnutls_pk_params_st params; - int pk_algorithm; - uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; - char buf[2 * GNUTLS_OPENPGP_KEYID_SIZE + 1]; - - if (key == NULL) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - result = gnutls_openpgp_privkey_get_preferred_key_id(key, keyid); - if (result == 0) { - uint32_t kid[2]; - - KEYID_IMPORT(kid, keyid); - - _gnutls_hard_log("Decrypting using PGP key ID %s\n", - _gnutls_bin2hex(keyid, - GNUTLS_OPENPGP_KEYID_SIZE, - buf, sizeof(buf), NULL)); - - result = - _gnutls_openpgp_privkey_get_mpis(key, kid, ¶ms); - - i = gnutls_openpgp_privkey_get_subkey_idx(key, keyid); - - pk_algorithm = - gnutls_openpgp_privkey_get_subkey_pk_algorithm(key, i, - NULL); - } else { - _gnutls_hard_log("Decrypting using master PGP key\n"); - - pk_algorithm = - gnutls_openpgp_privkey_get_pk_algorithm(key, NULL); - - result = - _gnutls_openpgp_privkey_get_mpis(key, NULL, ¶ms); - - } - - if (result < 0) { - gnutls_assert(); - return result; - } - - result = - _gnutls_pk_decrypt(pk_algorithm, plaintext, ciphertext, - ¶ms); - - gnutls_pk_params_clear(¶ms); - gnutls_pk_params_release(¶ms); - - if (result < 0) - return gnutls_assert_val(result); - - return 0; -} diff --git a/lib/openpgp_compat.c b/lib/openpgp_compat.c index 2a0bb5fb42..1e3badb8db 100644 --- a/lib/openpgp_compat.c +++ b/lib/openpgp_compat.c @@ -28,8 +28,6 @@ #include <gnutls/openpgp.h> #include <gnutls/abstract.h> -#ifndef ENABLE_OPENPGP - int gnutls_openpgp_crt_init(gnutls_openpgp_crt_t * key) { return GNUTLS_E_UNIMPLEMENTED_FEATURE; @@ -699,4 +697,3 @@ gnutls_openpgp_privkey_sign_hash(gnutls_openpgp_privkey_t key, return GNUTLS_E_UNIMPLEMENTED_FEATURE; } -#endif diff --git a/lib/pcert.c b/lib/pcert.c index 3fdce92017..56322e124c 100644 --- a/lib/pcert.c +++ b/lib/pcert.c @@ -26,9 +26,6 @@ #include <x509/common.h> #include <x509.h> #include "x509/x509_int.h" -#ifdef ENABLE_OPENPGP -#include "openpgp/openpgp.h" -#endif /** * gnutls_pcert_import_x509: @@ -270,142 +267,6 @@ int gnutls_pcert_import_x509_raw(gnutls_pcert_st * pcert, return ret; } -#ifdef ENABLE_OPENPGP - -/** - * gnutls_pcert_import_openpgp: - * @pcert: The pcert structure - * @crt: The raw certificate to be imported - * @flags: zero for now - * - * This convenience function will import the given certificate to a - * #gnutls_pcert_st structure. The structure must be deinitialized - * afterwards using gnutls_pcert_deinit(); - * - * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a - * negative error value. - * - * Since: 3.0 - **/ -int gnutls_pcert_import_openpgp(gnutls_pcert_st * pcert, - gnutls_openpgp_crt_t crt, - unsigned int flags) -{ - int ret; - size_t sz; - - memset(pcert, 0, sizeof(*pcert)); - - pcert->type = GNUTLS_CRT_OPENPGP; - pcert->cert.data = NULL; - - sz = 0; - ret = - gnutls_openpgp_crt_export(crt, GNUTLS_OPENPGP_FMT_RAW, NULL, - &sz); - if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER) { - ret = gnutls_assert_val(ret); - goto cleanup; - } - - pcert->cert.data = gnutls_malloc(sz); - if (pcert->cert.data == NULL) { - ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); - goto cleanup; - } - - ret = - gnutls_openpgp_crt_export(crt, GNUTLS_OPENPGP_FMT_RAW, - pcert->cert.data, &sz); - if (ret < 0) { - ret = gnutls_assert_val(ret); - goto cleanup; - } - pcert->cert.size = sz; - - ret = gnutls_pubkey_init(&pcert->pubkey); - if (ret < 0) { - ret = gnutls_assert_val(ret); - goto cleanup; - } - - ret = gnutls_pubkey_import_openpgp(pcert->pubkey, crt, 0); - if (ret < 0) { - gnutls_pubkey_deinit(pcert->pubkey); - pcert->pubkey = NULL; - ret = gnutls_assert_val(ret); - goto cleanup; - } - - return 0; - - cleanup: - _gnutls_free_datum(&pcert->cert); - - return ret; -} - -/** - * gnutls_pcert_import_openpgp_raw: - * @pcert: The pcert structure - * @cert: The raw certificate to be imported - * @format: The format of the certificate - * @keyid: The key ID to use (NULL for the master key) - * @flags: zero for now - * - * This convenience function will import the given certificate to a - * #gnutls_pcert_st structure. The structure must be deinitialized - * afterwards using gnutls_pcert_deinit(); - * - * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a - * negative error value. - * - * Since: 3.0 - **/ -int gnutls_pcert_import_openpgp_raw(gnutls_pcert_st * pcert, - const gnutls_datum_t * cert, - gnutls_openpgp_crt_fmt_t format, - gnutls_openpgp_keyid_t keyid, - unsigned int flags) -{ - int ret; - gnutls_openpgp_crt_t crt; - - memset(pcert, 0, sizeof(*pcert)); - - pcert->cert.data = NULL; - - ret = gnutls_openpgp_crt_init(&crt); - if (ret < 0) - return gnutls_assert_val(ret); - - ret = gnutls_openpgp_crt_import(crt, cert, format); - if (ret < 0) { - ret = gnutls_assert_val(ret); - goto cleanup; - } - - ret = gnutls_openpgp_crt_set_preferred_key_id(crt, keyid); - if (ret < 0) { - ret = gnutls_assert_val(ret); - goto cleanup; - } - - ret = gnutls_pcert_import_openpgp(pcert, crt, flags); - if (ret < 0) { - ret = gnutls_assert_val(ret); - goto cleanup; - } - ret = 0; - - cleanup: - gnutls_openpgp_crt_deinit(crt); - - return ret; -} - -#endif - /** * gnutls_pcert_export_x509: * @pcert: The pcert structure. @@ -446,50 +307,6 @@ int gnutls_pcert_export_x509(gnutls_pcert_st * pcert, return 0; } -#ifdef ENABLE_OPENPGP - -/** - * gnutls_pcert_export_x509: - * @pcert: The pcert structure. - * @crt: An initialized #gnutls_openpgp_crt_t. - * - * Converts the given #gnutls_pcert_t type into a #gnutls_openpgp_crt_t. - * This function only works if the type of @pcert is %GNUTLS_CRT_OPENPGP. - * When successful, the value written to @crt must be freed with - * gnutls_openpgp_crt_deinit() when no longer needed. - * - * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a - * negative error value. - * - * Since: 3.4.0 - */ -int gnutls_pcert_export_openpgp(gnutls_pcert_st * pcert, - gnutls_openpgp_crt_t * crt) -{ - int ret; - - if (pcert->type != GNUTLS_CRT_OPENPGP) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - ret = gnutls_openpgp_crt_init(crt); - if (ret < 0) - return gnutls_assert_val(ret); - - ret = gnutls_openpgp_crt_import(*crt, &pcert->cert, GNUTLS_OPENPGP_FMT_RAW); - if (ret < 0) { - gnutls_openpgp_crt_deinit(*crt); - *crt = NULL; - - return gnutls_assert_val(ret); - } - - return 0; -} - -#endif - /** * gnutls_pcert_deinit: * @pcert: The structure to be deinitialized @@ -521,16 +338,6 @@ _gnutls_get_auth_info_pcert(gnutls_pcert_st * pcert, [0], GNUTLS_X509_FMT_DER, GNUTLS_PCERT_NO_CERT); -#ifdef ENABLE_OPENPGP - case GNUTLS_CRT_OPENPGP: - return gnutls_pcert_import_openpgp_raw(pcert, - &info-> - raw_certificate_list - [0], - GNUTLS_OPENPGP_FMT_RAW, - info->subkey_id, - GNUTLS_PCERT_NO_CERT); -#endif default: gnutls_assert(); return GNUTLS_E_INTERNAL_ERROR; diff --git a/lib/priority.c b/lib/priority.c index 307618d334..761d0fe8b2 100644 --- a/lib/priority.c +++ b/lib/priority.c @@ -490,7 +490,6 @@ static const int cert_type_priority_default[] = { static const int cert_type_priority_all[] = { GNUTLS_CRT_X509, - GNUTLS_CRT_OPENPGP, 0 }; diff --git a/lib/privkey.c b/lib/privkey.c index 1c61bfe317..7d4cbb546b 100644 --- a/lib/privkey.c +++ b/lib/privkey.c @@ -30,8 +30,6 @@ #include <gnutls/abstract.h> #include <pk.h> #include <x509_int.h> -#include <openpgp/openpgp_int.h> -#include <openpgp/openpgp.h> #include <tls-sig.h> #include <algorithms.h> #include <fips.h> @@ -130,11 +128,6 @@ int gnutls_privkey_verify_seed(gnutls_privkey_t key, gnutls_digest_algorithm_t d int gnutls_privkey_get_pk_algorithm(gnutls_privkey_t key, unsigned int *bits) { switch (key->type) { -#ifdef ENABLE_OPENPGP - case GNUTLS_PRIVKEY_OPENPGP: - return gnutls_openpgp_privkey_get_pk_algorithm(key->key.openpgp, - bits); -#endif #ifdef ENABLE_PKCS11 case GNUTLS_PRIVKEY_PKCS11: return gnutls_pkcs11_privkey_get_pk_algorithm(key->key.pkcs11, @@ -230,33 +223,6 @@ _gnutls_privkey_get_mpis(gnutls_privkey_t key, gnutls_pk_params_st * params) int ret; switch (key->type) { -#ifdef ENABLE_OPENPGP - case GNUTLS_PRIVKEY_OPENPGP: - { - uint32_t kid[2]; - uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; - - ret = - gnutls_openpgp_privkey_get_preferred_key_id - (key->key.openpgp, keyid); - if (ret == 0) { - KEYID_IMPORT(kid, keyid); - ret = - _gnutls_openpgp_privkey_get_mpis - (key->key.openpgp, kid, params); - } else - ret = - _gnutls_openpgp_privkey_get_mpis - (key->key.openpgp, NULL, params); - - if (ret < 0) { - gnutls_assert(); - return ret; - } - } - - break; -#endif case GNUTLS_PRIVKEY_X509: ret = _gnutls_pk_params_copy(params, &key->key.x509->params); break; @@ -311,10 +277,6 @@ _gnutls_privkey_get_sign_params(gnutls_privkey_t key, gnutls_x509_spki_st * params) { switch (key->type) { -#ifdef ENABLE_OPENPGP - case GNUTLS_PRIVKEY_OPENPGP: - break; -#endif #ifdef ENABLE_PKCS11 case GNUTLS_PRIVKEY_PKCS11: break; @@ -345,10 +307,6 @@ _gnutls_privkey_update_sign_params(gnutls_privkey_t key, gnutls_x509_spki_st *params) { switch (key->type) { -#ifdef ENABLE_OPENPGP - case GNUTLS_PRIVKEY_OPENPGP: - break; -#endif #ifdef ENABLE_PKCS11 case GNUTLS_PRIVKEY_PKCS11: break; @@ -460,11 +418,6 @@ void gnutls_privkey_deinit(gnutls_privkey_t key) if (key->flags & GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE || key->flags & GNUTLS_PRIVKEY_IMPORT_COPY) switch (key->type) { -#ifdef ENABLE_OPENPGP - case GNUTLS_PRIVKEY_OPENPGP: - gnutls_openpgp_privkey_deinit(key->key.openpgp); - break; -#endif #ifdef ENABLE_PKCS11 case GNUTLS_PRIVKEY_PKCS11: gnutls_pkcs11_privkey_deinit(key->key.pkcs11); @@ -1007,177 +960,6 @@ gnutls_privkey_generate2(gnutls_privkey_t pkey, return 0; } -#ifdef ENABLE_OPENPGP -/** - * gnutls_privkey_import_openpgp: - * @pkey: The private key - * @key: The private key to be imported - * @flags: Flags for the import - * - * This function will import the given private key to the abstract - * #gnutls_privkey_t type. - * - * The #gnutls_openpgp_privkey_t object must not be deallocated - * during the lifetime of this structure. The subkey set as - * preferred will be used, or the master key otherwise. - * - * @flags might be zero or one of %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE - * and %GNUTLS_PRIVKEY_IMPORT_COPY. - * - * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a - * negative error value. - * - * Since: 2.12.0 - **/ -int -gnutls_privkey_import_openpgp(gnutls_privkey_t pkey, - gnutls_openpgp_privkey_t key, unsigned int flags) -{ - int ret, idx; - uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; - - ret = check_if_clean(pkey); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - if (flags & GNUTLS_PRIVKEY_IMPORT_COPY) { - ret = gnutls_openpgp_privkey_init(&pkey->key.openpgp); - if (ret < 0) - return gnutls_assert_val(ret); - - ret = _gnutls_openpgp_privkey_cpy(pkey->key.openpgp, key); - if (ret < 0) { - gnutls_openpgp_privkey_deinit(pkey->key.openpgp); - return gnutls_assert_val(ret); - } - } else - pkey->key.openpgp = key; - - pkey->type = GNUTLS_PRIVKEY_OPENPGP; - - ret = gnutls_openpgp_privkey_get_preferred_key_id(key, keyid); - if (ret == GNUTLS_E_OPENPGP_PREFERRED_KEY_ERROR) { - pkey->pk_algorithm = - gnutls_openpgp_privkey_get_pk_algorithm(key, NULL); - } else { - if (ret < 0) - return gnutls_assert_val(ret); - - idx = gnutls_openpgp_privkey_get_subkey_idx(key, keyid); - - pkey->pk_algorithm = - gnutls_openpgp_privkey_get_subkey_pk_algorithm(key, - idx, NULL); - } - - pkey->flags = flags; - - return 0; -} - -/** - * gnutls_privkey_import_openpgp_raw: - * @pkey: The private key - * @data: The private key data to be imported - * @format: The format of the private key - * @keyid: The key id to use (optional) - * @password: A password (optional) - * - * This function will import the given private key to the abstract - * #gnutls_privkey_t type. - * - * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a - * negative error value. - * - * Since: 3.1.0 - **/ -int gnutls_privkey_import_openpgp_raw(gnutls_privkey_t pkey, - const gnutls_datum_t * data, - gnutls_openpgp_crt_fmt_t format, - const gnutls_openpgp_keyid_t keyid, - const char *password) -{ - gnutls_openpgp_privkey_t xpriv; - int ret; - - ret = gnutls_openpgp_privkey_init(&xpriv); - if (ret < 0) - return gnutls_assert_val(ret); - - ret = gnutls_openpgp_privkey_import(xpriv, data, format, password, 0); - if (ret < 0) { - gnutls_assert(); - goto cleanup; - } - - if (keyid) { - ret = gnutls_openpgp_privkey_set_preferred_key_id(xpriv, keyid); - if (ret < 0) { - gnutls_assert(); - goto cleanup; - } - } - - ret = - gnutls_privkey_import_openpgp(pkey, xpriv, - GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE); - if (ret < 0) { - gnutls_assert(); - goto cleanup; - } - - return 0; - - cleanup: - gnutls_openpgp_privkey_deinit(xpriv); - - return ret; -} - -/** - * gnutls_privkey_export_openpgp: - * @pkey: The private key - * @key: Location for the key to be exported. - * - * Converts the given abstract private key to a #gnutls_openpgp_privkey_t - * type. The key must be of type %GNUTLS_PRIVKEY_OPENPGP. The key - * returned in @key must be deinitialized with - * gnutls_openpgp_privkey_deinit(). - * - * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a - * negative error value. - * - * Since: 3.4.0 - */ -int -gnutls_privkey_export_openpgp(gnutls_privkey_t pkey, - gnutls_openpgp_privkey_t *key) -{ - int ret; - - if (pkey->type != GNUTLS_PRIVKEY_OPENPGP) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - ret = gnutls_openpgp_privkey_init(key); - if (ret < 0) - return gnutls_assert_val(ret); - - ret = _gnutls_openpgp_privkey_cpy(*key, pkey->key.openpgp); - if (ret < 0) { - gnutls_openpgp_privkey_deinit(*key); - *key = NULL; - - return gnutls_assert_val(ret); - } - - return 0; -} -#endif - /** * gnutls_privkey_sign_data: * @signer: Holds the key @@ -1502,11 +1284,6 @@ _gnutls_privkey_sign_raw_data(gnutls_privkey_t key, gnutls_x509_spki_st * params) { switch (key->type) { -#ifdef ENABLE_OPENPGP - case GNUTLS_PRIVKEY_OPENPGP: - return gnutls_openpgp_privkey_sign_hash(key->key.openpgp, - data, signature); -#endif #ifdef ENABLE_PKCS11 case GNUTLS_PRIVKEY_PKCS11: return _gnutls_pkcs11_privkey_sign_hash(key->key.pkcs11, @@ -1548,12 +1325,6 @@ gnutls_privkey_decrypt_data(gnutls_privkey_t key, gnutls_datum_t * plaintext) { switch (key->type) { -#ifdef ENABLE_OPENPGP - case GNUTLS_PRIVKEY_OPENPGP: - return _gnutls_openpgp_privkey_decrypt_data(key->key.openpgp, - flags, ciphertext, - plaintext); -#endif case GNUTLS_PRIVKEY_X509: return _gnutls_pk_decrypt(key->pk_algorithm, plaintext, ciphertext, &key->key.x509->params); diff --git a/lib/privkey_raw.c b/lib/privkey_raw.c index 6c723ff8b5..76e9c43f39 100644 --- a/lib/privkey_raw.c +++ b/lib/privkey_raw.c @@ -27,8 +27,6 @@ #include <gnutls/abstract.h> #include <pk.h> #include <x509_int.h> -#include <openpgp/openpgp_int.h> -#include <openpgp/openpgp.h> #include <tls-sig.h> #include <algorithms.h> #include <fips.h> diff --git a/lib/pubkey.c b/lib/pubkey.c index 5df44e2c6d..b345871073 100644 --- a/lib/pubkey.c +++ b/lib/pubkey.c @@ -29,7 +29,6 @@ #include <tls-sig.h> #include <pk.h> #include <x509_int.h> -#include <openpgp/openpgp_int.h> #include <num.h> #include <x509/common.h> #include <x509_b64.h> @@ -402,239 +401,6 @@ gnutls_pubkey_import_pkcs11(gnutls_pubkey_t key, #endif /* ENABLE_PKCS11 */ -#ifdef ENABLE_OPENPGP - -#define OPENPGP_KEY_PRIMARY 2 -#define OPENPGP_KEY_SUBKEY 1 - - -/** - * gnutls_pubkey_import_openpgp: - * @key: The public key - * @crt: The certificate to be imported - * @flags: should be zero - * - * Imports a public key from an openpgp key. This function will import - * the given public key to the abstract #gnutls_pubkey_t - * type. The subkey set as preferred will be imported or the - * master key otherwise. - * - * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a - * negative error value. - * - * Since: 2.12.0 - **/ -int -gnutls_pubkey_import_openpgp(gnutls_pubkey_t key, - gnutls_openpgp_crt_t crt, unsigned int flags) -{ - int ret, idx; - uint32_t kid32[2]; - uint32_t *k; - uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; - size_t len; - - len = sizeof(key->openpgp_key_fpr); - ret = - gnutls_openpgp_crt_get_fingerprint(crt, key->openpgp_key_fpr, - &len); - if (ret < 0) - return gnutls_assert_val(ret); - key->openpgp_key_fpr_set = 1; - - ret = gnutls_openpgp_crt_get_preferred_key_id(crt, keyid); - if (ret == GNUTLS_E_OPENPGP_PREFERRED_KEY_ERROR) { - key->pk_algorithm = - gnutls_openpgp_crt_get_pk_algorithm(crt, &key->bits); - key->openpgp_key_id_set = OPENPGP_KEY_PRIMARY; - - ret = - gnutls_openpgp_crt_get_key_id(crt, - key->openpgp_key_id); - if (ret < 0) - return gnutls_assert_val(ret); - - ret = - gnutls_openpgp_crt_get_key_usage(crt, &key->key_usage); - if (ret < 0) - key->key_usage = 0; - - k = NULL; - } else { - if (ret < 0) { - gnutls_assert(); - return ret; - } - key->openpgp_key_id_set = OPENPGP_KEY_SUBKEY; - - KEYID_IMPORT(kid32, keyid); - k = kid32; - - idx = gnutls_openpgp_crt_get_subkey_idx(crt, keyid); - - ret = - gnutls_openpgp_crt_get_subkey_id(crt, idx, - key->openpgp_key_id); - if (ret < 0) - return gnutls_assert_val(ret); - - ret = - gnutls_openpgp_crt_get_subkey_usage(crt, idx, - &key->key_usage); - if (ret < 0) - key->key_usage = 0; - - key->pk_algorithm = - gnutls_openpgp_crt_get_subkey_pk_algorithm(crt, idx, - NULL); - } - - ret = _gnutls_openpgp_crt_get_mpis(crt, k, &key->params); - if (ret < 0) - return gnutls_assert_val(ret); - - return 0; -} - -/** - * gnutls_pubkey_get_openpgp_key_id: - * @key: Holds the public key - * @flags: should be 0 or %GNUTLS_PUBKEY_GET_OPENPGP_FINGERPRINT - * @output_data: will contain the key ID - * @output_data_size: holds the size of output_data (and will be - * replaced by the actual size of parameters) - * @subkey: Will be non zero if the key ID corresponds to a subkey - * - * This function returns the OpenPGP key ID of the corresponding key. - * The key is a unique ID that depends on the public - * key parameters. - * - * If the flag %GNUTLS_PUBKEY_GET_OPENPGP_FINGERPRINT is specified - * this function returns the fingerprint of the master key. - * - * If the buffer provided is not long enough to hold the output, then - * *output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will - * be returned. The output is %GNUTLS_OPENPGP_KEYID_SIZE bytes long. - * - * Returns: In case of failure a negative error code will be - * returned, and 0 on success. - * - * Since: 3.0 - **/ -int -gnutls_pubkey_get_openpgp_key_id(gnutls_pubkey_t key, unsigned int flags, - unsigned char *output_data, - size_t * output_data_size, - unsigned int *subkey) -{ - if (key == NULL) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - if (flags & GNUTLS_PUBKEY_GET_OPENPGP_FINGERPRINT) { - if (*output_data_size < sizeof(key->openpgp_key_fpr)) { - *output_data_size = sizeof(key->openpgp_key_fpr); - return - gnutls_assert_val - (GNUTLS_E_SHORT_MEMORY_BUFFER); - } - - if (key->openpgp_key_fpr_set == 0) - return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); - - if (output_data) - memcpy(output_data, key->openpgp_key_fpr, - sizeof(key->openpgp_key_fpr)); - *output_data_size = sizeof(key->openpgp_key_fpr); - - return 0; - } - - if (*output_data_size < sizeof(key->openpgp_key_id)) { - *output_data_size = sizeof(key->openpgp_key_id); - return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER); - } - - if (key->openpgp_key_id_set == 0) - return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); - - if (subkey) { - if (key->openpgp_key_id_set == OPENPGP_KEY_SUBKEY) - *subkey = 1; - else - *subkey = 0; - } - - if (output_data) { - memcpy(output_data, key->openpgp_key_id, - sizeof(key->openpgp_key_id)); - } - *output_data_size = sizeof(key->openpgp_key_id); - - return 0; -} - -/** - * gnutls_pubkey_import_openpgp_raw: - * @pkey: The public key - * @data: The public key data to be imported - * @format: The format of the public key - * @keyid: The key id to use (optional) - * @flags: Should be zero - * - * This function will import the given public key to the abstract - * #gnutls_pubkey_t type. - * - * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a - * negative error value. - * - * Since: 3.1.3 - **/ -int gnutls_pubkey_import_openpgp_raw(gnutls_pubkey_t pkey, - const gnutls_datum_t * data, - gnutls_openpgp_crt_fmt_t format, - const gnutls_openpgp_keyid_t keyid, - unsigned int flags) -{ - gnutls_openpgp_crt_t xpriv; - int ret; - - ret = gnutls_openpgp_crt_init(&xpriv); - if (ret < 0) - return gnutls_assert_val(ret); - - ret = gnutls_openpgp_crt_import(xpriv, data, format); - if (ret < 0) { - gnutls_assert(); - goto cleanup; - } - - if (keyid) { - ret = - gnutls_openpgp_crt_set_preferred_key_id(xpriv, keyid); - if (ret < 0) { - gnutls_assert(); - goto cleanup; - } - } - - ret = gnutls_pubkey_import_openpgp(pkey, xpriv, flags); - if (ret < 0) { - gnutls_assert(); - goto cleanup; - } - - ret = 0; - - cleanup: - gnutls_openpgp_crt_deinit(xpriv); - - return ret; -} - -#endif - /** * gnutls_pubkey_export: * @key: Holds the certificate diff --git a/lib/state.c b/lib/state.c index 9dc3128312..c9e8d20085 100644 --- a/lib/state.c +++ b/lib/state.c @@ -669,25 +669,6 @@ _gnutls_dh_set_group(gnutls_session_t session, bigint_t gen, return 0; } -#ifdef ENABLE_OPENPGP -/** - * gnutls_openpgp_send_cert: - * @session: a #gnutls_session_t type. - * @status: is one of GNUTLS_OPENPGP_CERT, or GNUTLS_OPENPGP_CERT_FINGERPRINT - * - * This function will order gnutls to send the key fingerprint - * instead of the key in the initial handshake procedure. This should - * be used with care and only when there is indication or knowledge - * that the server can obtain the client's key. - **/ -void -gnutls_openpgp_send_cert(gnutls_session_t session, - gnutls_openpgp_crt_status_t status) -{ - session->internals.pgp_fingerprint = status; -} -#endif - /** * gnutls_certificate_send_x509_rdn_sequence: * @session: a #gnutls_session_t type. @@ -709,13 +690,6 @@ gnutls_certificate_send_x509_rdn_sequence(gnutls_session_t session, session->internals.ignore_rdn_sequence = status; } -#ifdef ENABLE_OPENPGP -int _gnutls_openpgp_send_fingerprint(gnutls_session_t session) -{ - return session->internals.pgp_fingerprint; -} -#endif - /*- * _gnutls_record_set_default_version - Used to set the default version for the first record packet * @session: is a #gnutls_session_t type. diff --git a/lib/verify-tofu.c b/lib/verify-tofu.c index 02b427c508..942d692650 100644 --- a/lib/verify-tofu.c +++ b/lib/verify-tofu.c @@ -43,8 +43,6 @@ struct gnutls_tdb_int { static int raw_pubkey_to_base64(const gnutls_datum_t * raw, gnutls_datum_t * b64); -static int pgp_crt_to_raw_pubkey(const gnutls_datum_t * cert, - gnutls_datum_t * rpubkey); static int verify_pubkey(const char *file, const char *host, const char *service, const gnutls_datum_t * skey); @@ -116,8 +114,7 @@ gnutls_verify_stored_pubkey(const char *db_name, int ret; char local_file[MAX_FILENAME]; - if (cert_type != GNUTLS_CRT_X509 - && cert_type != GNUTLS_CRT_OPENPGP) + if (cert_type != GNUTLS_CRT_X509) return gnutls_assert_val (GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE); @@ -132,11 +129,7 @@ gnutls_verify_stored_pubkey(const char *db_name, if (tdb == NULL) tdb = &default_tdb; - if (cert_type == GNUTLS_CRT_X509) - ret = x509_raw_crt_to_raw_pubkey(cert, &pubkey); - else - ret = pgp_crt_to_raw_pubkey(cert, &pubkey); - + ret = x509_raw_crt_to_raw_pubkey(cert, &pubkey); if (ret < 0) { gnutls_assert(); goto cleanup; @@ -383,74 +376,6 @@ static int raw_pubkey_to_base64(const gnutls_datum_t * raw, return 0; } -static int pgp_crt_to_raw_pubkey(const gnutls_datum_t * cert, - gnutls_datum_t * rpubkey) -{ -#ifdef ENABLE_OPENPGP - gnutls_openpgp_crt_t crt = NULL; - gnutls_pubkey_t pubkey = NULL; - size_t size; - int ret; - - ret = gnutls_openpgp_crt_init(&crt); - if (ret < 0) - return gnutls_assert_val(ret); - - ret = gnutls_pubkey_init(&pubkey); - if (ret < 0) { - gnutls_assert(); - goto cleanup; - } - - ret = gnutls_openpgp_crt_import(crt, cert, GNUTLS_OPENPGP_FMT_RAW); - if (ret < 0) { - gnutls_assert(); - goto cleanup; - } - - ret = gnutls_pubkey_import_openpgp(pubkey, crt, 0); - if (ret < 0) { - gnutls_assert(); - goto cleanup; - } - - size = 0; - ret = - gnutls_pubkey_export(pubkey, GNUTLS_X509_FMT_DER, NULL, &size); - if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER) { - gnutls_assert(); - goto cleanup; - } - - rpubkey->data = gnutls_malloc(size); - if (rpubkey->data == NULL) { - ret = GNUTLS_E_MEMORY_ERROR; - gnutls_assert(); - goto cleanup; - } - - ret = - gnutls_pubkey_export(pubkey, GNUTLS_X509_FMT_DER, - rpubkey->data, &size); - if (ret < 0) { - gnutls_free(rpubkey->data); - gnutls_assert(); - goto cleanup; - } - - rpubkey->size = size; - ret = 0; - - cleanup: - gnutls_openpgp_crt_deinit(crt); - gnutls_pubkey_deinit(pubkey); - - return ret; -#else - return GNUTLS_E_UNIMPLEMENTED_FEATURE; -#endif -} - static int store_pubkey(const char *db_name, const char *host, const char *service, time_t expiration, @@ -568,8 +493,7 @@ gnutls_store_pubkey(const char *db_name, int ret; char local_file[MAX_FILENAME]; - if (cert_type != GNUTLS_CRT_X509 - && cert_type != GNUTLS_CRT_OPENPGP) + if (cert_type != GNUTLS_CRT_X509) return gnutls_assert_val (GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE); @@ -593,10 +517,7 @@ gnutls_store_pubkey(const char *db_name, if (tdb == NULL) tdb = &default_tdb; - if (cert_type == GNUTLS_CRT_X509) - ret = x509_raw_crt_to_raw_pubkey(cert, &pubkey); - else - ret = pgp_crt_to_raw_pubkey(cert, &pubkey); + ret = x509_raw_crt_to_raw_pubkey(cert, &pubkey); if (ret < 0) { gnutls_assert(); goto cleanup; diff --git a/lib/x509/Makefile.am b/lib/x509/Makefile.am index 46d567ed95..946ed4afaa 100644 --- a/lib/x509/Makefile.am +++ b/lib/x509/Makefile.am @@ -23,8 +23,7 @@ AM_CPPFLAGS = \ -I$(builddir)/../../gl \ -I$(srcdir)/../includes \ -I$(builddir)/../includes \ - -I$(srcdir)/.. \ - $(LIBOPENCDK_CFLAGS) + -I$(srcdir)/.. if ENABLE_MINITASN1 AM_CPPFLAGS += -I$(srcdir)/../minitasn1 diff --git a/m4/hooks.m4 b/m4/hooks.m4 index c4e2cd9107..a695665e06 100644 --- a/m4/hooks.m4 +++ b/m4/hooks.m4 @@ -302,21 +302,6 @@ LIBTASN1_MINIMUM=4.9 fi AM_CONDITIONAL(ENABLE_ECDHE, test "$ac_enable_ecdhe" != "no") - ac_enable_openpgp=no - AC_MSG_CHECKING([whether to enable OpenPGP Certificate authentication support]) - AC_ARG_ENABLE(openpgp-authentication, - AS_HELP_STRING([--enable-openpgp-authentication], - [enable the OpenPGP authentication support]), - ac_enable_openpgp=$enableval) - if test x$ac_enable_openpgp = xno; then - AC_MSG_RESULT(yes) - ac_full=0 - else - AC_DEFINE([ENABLE_OPENPGP], 1, [use openpgp authentication]) - AC_MSG_RESULT(no) - fi - AM_CONDITIONAL(ENABLE_OPENPGP, test "$ac_enable_openpgp" = "yes") - # For cryptodev AC_MSG_CHECKING([whether to add cryptodev support]) AC_ARG_ENABLE(cryptodev, diff --git a/tests/Makefile.am b/tests/Makefile.am index 2f1142c471..7d0a6dcadd 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -105,7 +105,7 @@ ctests = mini-record-2 simple gc set_pkcs12_cred cert certuniqueid \ crlverify mini-dtls-discard init_fds mini-record-failure \ tls-rehandshake-cert-2 custom-urls set_x509_key_mem set_x509_key_file \ mini-chain-unsorted x509-verify-with-crl mini-dtls-mtu privkey-verify-broken \ - mini-dtls-record-asym openpgp-callback key-import-export \ + mini-dtls-record-asym key-import-export \ mini-dtls-fork mini-dtls-pthread mini-key-material x509cert-invalid \ tls-ext-register tls-supplemental mini-dtls0-9 duplicate-extensions \ mini-record-retvals mini-server-name tls-etm x509-cert-callback \ @@ -263,18 +263,9 @@ ctests += openssl openssl_LDADD = ../extra/libgnutls-openssl.la $(LDADD) endif -if ENABLE_OPENPGP -ctests += openpgp-auth openpgp-auth2 openpgp-keyring pgps2kgnu -endif - if HAVE_FORK ctests += x509self x509dn anonself pskself dhepskself \ setcredcrash resume-x509 resume-psk resume-anon - -if ENABLE_OPENPGP -ctests += openpgpself -endif - endif gc_CPPFLAGS = $(AM_CPPFLAGS) \ diff --git a/tests/cert-tests/Makefile.am b/tests/cert-tests/Makefile.am index 3ebe13604f..5487b11045 100644 --- a/tests/cert-tests/Makefile.am +++ b/tests/cert-tests/Makefile.am @@ -15,9 +15,8 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # -# You should have received a copy of the GNU General Public License -# along with this file; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/> EXTRA_DIST = data/ca-no-pathlen.pem data/no-ca-or-pathlen.pem data/aki-cert.pem \ data/template-test.key data/template-test.pem templates/template-test.tmpl \ @@ -62,11 +61,9 @@ EXTRA_DIST = data/ca-no-pathlen.pem data/no-ca-or-pathlen.pem data/aki-cert.pem data/code-signing-ca.pem data/code-signing-cert.pem data/multi-value-dn.pem \ data/pkcs7-cat-ca.pem data/pkcs7-cat.p7 data/openssl.p7b data/openssl.p7b.out \ data/openssl-keyid.p7b data/openssl-keyid.p7b.out data/openssl.p12 \ - data/openpgp-invalid1.pub data/openpgp-invalid2.pub data/openpgp-invalid3.pub \ data/x509-v1-with-sid.pem data/x509-v1-with-iid.pem data/x509-v3-with-fractional-time.pem \ - data/openpgp-invalid5.pub data/openpgp-invalid6.pub templates/template-long-dns.tmpl \ - data/long-dns.pem data/template-long-dns-crq.pem data/openpgp-invalid7.pub \ - data/openpgp-invalid8.pub data/chain-with-critical-on-root.pem \ + templates/template-long-dns.tmpl \ + data/long-dns.pem data/template-long-dns-crq.pem data/chain-with-critical-on-root.pem \ data/chain-with-critical-on-intermediate.pem data/chain-with-critical-on-endcert.pem \ templates/crit-extensions.tmpl data/crit-extensions.pem data/x509-with-zero-version.pem \ data/key-corpus-rc2-1.p12 data/key-corpus-rc2-2.p12 data/key-corpus-rc2-3.p12 \ @@ -90,16 +87,6 @@ if WANT_TEST_SUITE dist_check_SCRIPTS += provable-dh-default endif -if ENABLE_OPENPGP -# The selftest is disabled until we can make it work under Wine and -# under Debian buildds (problem with 127.0.0.2?). -dist_check_SCRIPTS += openpgp-selfsigs -dist_check_SCRIPTS += openpgp-cert-parser -if !WINDOWS -dist_check_SCRIPTS += openpgp-certs -endif -endif - dist_check_SCRIPTS += certtool-utf8 crq if !WINDOWS |