From 913f584b7630fc38a9705bbbabe7c5acdefef37e Mon Sep 17 00:00:00 2001 From: "T. von Dein" Date: Mon, 24 Nov 2025 23:02:13 +0100 Subject: [PATCH] migrate to codeberg (#21) --- .woodpecker/build.yaml | 29 + .woodpecker/release.sh | 54 ++ .woodpecker/release.yaml | 28 + .woodpecker/test.sh | 19 + README | 182 ------ README.md | 187 ++++++ README.pod | 217 ------- VERSION | 2 +- autogen.sh | 119 ---- configure.ac | 383 ------------ libpcp/Makefile.am | 38 -- libpcp/config.h.in | 17 + {include => libpcp/include}/Makefile.am | 0 {include => libpcp/include}/pcp.h | 0 {include => libpcp/include}/pcp/buffer.h | 0 {include => libpcp/include}/pcp/config.h.in | 0 {include => libpcp/include}/pcp/context.h | 0 {include => libpcp/include}/pcp/crypto.h | 0 {include => libpcp/include}/pcp/defines.h | 0 {include => libpcp/include}/pcp/ed.h | 0 {include => libpcp/include}/pcp/getpass.h | 0 {include => libpcp/include}/pcp/jenhash.h | 0 {include => libpcp/include}/pcp/key.h | 0 {include => libpcp/include}/pcp/keyhash.h | 0 {include => libpcp/include}/pcp/keysig.h | 0 {include => libpcp/include}/pcp/mem.h | 0 {include => libpcp/include}/pcp/mgmt.h | 78 +-- {include => libpcp/include}/pcp/pcpstream.h | 0 {include => libpcp/include}/pcp/platform.h | 0 {include => libpcp/include}/pcp/plist.h | 0 {include => libpcp/include}/pcp/randomart.h | 0 {include => libpcp/include}/pcp/readpass.h | 0 {include => libpcp/include}/pcp/scrypt.h | 0 {include => libpcp/include}/pcp/structs.h | 0 {include => libpcp/include}/pcp/uthash.h | 0 {include => libpcp/include}/pcp/util.h | 0 {include => libpcp/include}/pcp/vault.h | 0 {include => libpcp/include}/pcp/version.h | 0 {include => libpcp/include}/pcp/z85.h | 0 {include => libpcp/include}/pcp/zmq_z85.h | 0 libpcp/key.c | 246 ++++---- libpcp/meson.build | 64 ++ libpcp/mgmt.c | 536 ++++++++-------- meson.build | 120 ++++ meson_options.txt | 1 + src/compat_getopt.h | 20 +- src/encryption.h | 19 +- src/keymgmt.c | 432 ++++++------- src/keymgmt.h | 32 +- src/pcp.c | 655 ++++++++++---------- src/pcp.h | 75 +-- src/z85util.c | 55 +- tests/iotests.cfg | 27 +- tests/jsonunittests.cfg | 2 +- tests/md5 | 2 +- tests/meson.build | 54 ++ tests/pwhashes.c | 29 +- tests/unittests.cfg | 40 +- tests/unittests.sh | 12 +- 59 files changed, 1702 insertions(+), 2072 deletions(-) create mode 100644 .woodpecker/build.yaml create mode 100755 .woodpecker/release.sh create mode 100644 .woodpecker/release.yaml create mode 100755 .woodpecker/test.sh delete mode 100644 README create mode 100644 README.md delete mode 100644 README.pod delete mode 100755 autogen.sh delete mode 100755 configure.ac delete mode 100644 libpcp/Makefile.am create mode 100644 libpcp/config.h.in rename {include => libpcp/include}/Makefile.am (100%) rename {include => libpcp/include}/pcp.h (100%) rename {include => libpcp/include}/pcp/buffer.h (100%) rename {include => libpcp/include}/pcp/config.h.in (100%) rename {include => libpcp/include}/pcp/context.h (100%) rename {include => libpcp/include}/pcp/crypto.h (100%) rename {include => libpcp/include}/pcp/defines.h (100%) rename {include => libpcp/include}/pcp/ed.h (100%) rename {include => libpcp/include}/pcp/getpass.h (100%) rename {include => libpcp/include}/pcp/jenhash.h (100%) rename {include => libpcp/include}/pcp/key.h (100%) rename {include => libpcp/include}/pcp/keyhash.h (100%) rename {include => libpcp/include}/pcp/keysig.h (100%) rename {include => libpcp/include}/pcp/mem.h (100%) rename {include => libpcp/include}/pcp/mgmt.h (85%) rename {include => libpcp/include}/pcp/pcpstream.h (100%) rename {include => libpcp/include}/pcp/platform.h (100%) rename {include => libpcp/include}/pcp/plist.h (100%) rename {include => libpcp/include}/pcp/randomart.h (100%) rename {include => libpcp/include}/pcp/readpass.h (100%) rename {include => libpcp/include}/pcp/scrypt.h (100%) rename {include => libpcp/include}/pcp/structs.h (100%) rename {include => libpcp/include}/pcp/uthash.h (100%) rename {include => libpcp/include}/pcp/util.h (100%) rename {include => libpcp/include}/pcp/vault.h (100%) rename {include => libpcp/include}/pcp/version.h (100%) rename {include => libpcp/include}/pcp/z85.h (100%) rename {include => libpcp/include}/pcp/zmq_z85.h (100%) create mode 100644 libpcp/meson.build create mode 100644 meson.build create mode 100644 meson_options.txt create mode 100644 tests/meson.build diff --git a/.woodpecker/build.yaml b/.woodpecker/build.yaml new file mode 100644 index 0000000..2cab881 --- /dev/null +++ b/.woodpecker/build.yaml @@ -0,0 +1,29 @@ +matrix: + platform: + - linux/amd64 + +labels: + platform: ${platform} + +steps: + build: + when: + event: [push] + image: alpine:latest + commands: + - apk update + - apk add --no-cache bash build-base gdb perl libsodium libsodium-dev libbsd libbsd-dev jansson jansson-dev db db-dev pkgconfig meson ninja + - meson setup --reconfigure build + - ninja -C build + + test: + when: + event: [push] + image: alpine:latest + commands: + - apk update + - apk add --no-cache bash build-base gdb perl libsodium libsodium-dev libbsd libbsd-dev jansson jansson-dev db db-dev pkgconfig meson ninja + - meson setup --reconfigure build + - ninja -C build test + + diff --git a/.woodpecker/release.sh b/.woodpecker/release.sh new file mode 100755 index 0000000..a44513a --- /dev/null +++ b/.woodpecker/release.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +# This is my own simple codeberg generic releaser. It takes to +# binaries to be uploaded as arguments and takes every other args from +# env. Works on tags or normal commits (push), tags must start with v. + + +set -e + +die() { + echo $* + exit 1 +} + +if test -z "$DEPLOY_TOKEN"; then + die "token DEPLOY_TOKEN not set" +fi + +git fetch --all + +# determine current tag or commit hash +version="$CI_COMMIT_TAG" +previous="" +log="" +if test -z "$version"; then + version="${CI_COMMIT_SHA:0:6}" + log=$(git log -1 --oneline) +else + previous=$(git tag -l | grep -E "^v" | tac | grep -A1 "$version" | tail -1) + log=$(git log -1 --oneline "${previous}..${version}" | sed 's|^|- |g') +fi + +# release body +printf "# Changes\n\n %s\n" "$log" > body.txt + +# create the release +https --ignore-stdin --check-status -b -A bearer -a "$DEPLOY_TOKEN" POST \ + "https://codeberg.org/api/v1/repos/${CI_REPO_OWNER}/${CI_REPO_NAME}/releases" \ + tag_name="$version" name="Release $version" body=@body.txt > release.json + +# we need the id to upload files +ID=$(jq -r .id < release.json) + +if test -z "$ID"; then + cat release.json + die "failed to create release" +fi + +# actually upload +for file in "$@"; do + https --ignore-stdin --check-status -A bearer -a "$DEPLOY_TOKEN" -f POST \ + "https://codeberg.org/api/v1/repos/${CI_REPO_OWNER}/${CI_REPO_NAME}/releases/$ID/assets" \ + "name=${file}" "attachment@${file}" +done diff --git a/.woodpecker/release.yaml b/.woodpecker/release.yaml new file mode 100644 index 0000000..69ab14f --- /dev/null +++ b/.woodpecker/release.yaml @@ -0,0 +1,28 @@ +# build release + +labels: + platform: linux/amd64 + +steps: + dist: + when: + event: [tag,manual] + image: alpine:latest + commands: + - apk update + - apk add --no-cache bash build-base gdb perl libsodium libsodium-dev libbsd libbsd-dev jansson jansson-dev db db-dev pkgconfig meson ninja git + - meson setup --reconfigure --buildtype=release build + - meson dist -C build --formats xztar,gztar,zip --no-tests + - mv build/meson-dist/* . + + release: + image: alpine:latest + when: + event: [tag,manual] + environment: + DEPLOY_TOKEN: + from_secret: DEPLOY_TOKEN + commands: + - apk update + - apk add --no-cache bash httpie jq git + - .woodpecker/release.sh pcp-* diff --git a/.woodpecker/test.sh b/.woodpecker/test.sh new file mode 100755 index 0000000..d19eba1 --- /dev/null +++ b/.woodpecker/test.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +yq '.steps.test-gdbm.commands' < .woodpecker/build.yaml \ + | grep -- - | grep -v apk | sed 's/^\- //' \ + | while read COMMAND; do + echo "$COMMAND" | bash -e > debug.log 2>&1 + if test $? -ne 0; then + echo "fail - $COMMAND" + if test -s debug.log; then + cat debug.log + else + echo exit 1 + fi + else + echo "ok - $COMMAND" + fi +done + +rm -f debug.log diff --git a/README b/README deleted file mode 100644 index eab92e4..0000000 --- a/README +++ /dev/null @@ -1,182 +0,0 @@ -DESCRIPTION - Pretty Curved Privacy (pcp1) is a commandline utility which can be used - to encrypt files. pcp1 uses eliptc curve cryptography for encryption - (CURVE25519 by Dan J. Bernstein). While CURVE25519 is no worldwide - accepted standard it hasn't been compromised by the NSA - which might be - better, depending on your point of view. - - Caution: since CURVE25519 is no accepted standard, pcp1 has to be - considered as experimental software. In fact, I wrote it just to learn - about the curve and see how it works. - - Beside some differences it works like GNUPG. So, if you already know how - to use gpg, you'll feel almost home. - -QUICKSTART - Lets say, Alicia and Bobby want to exchange encrypted messages. Here's - what the've got to do. - - First, both have create a secret key: - - Alicia Bobby - pcp1 -k pcp1 -k - - After entering their name, email address and a passphrase to protect the - key, it will be stored in their vault file (by default ~/.pcpvault). - - Now, both of them have to export the public key, which has to be - imported by the other one. With pcp you can export the public part of - your primary key, but the better solution is to export a derived public - key especially for the recipient: - - Alicia Bobby - pcp1 -p -r Bobby -O alicia.pub pcp1 -p -r Alicia -O bobby.pub - - They've to exchange the public key somehow (which is not my problem at - the moment, use ssh, encrypted mail, whatever). Once exchanged, they - have to import it: - - Alicia Bobby - pcp1 -K -I bobby.pub pcp1 -K -I alicia.pub - - They will see a response as this when done: - - key 0x29A323A2C295D391 added to .pcpvault. - - Now, Alicia finally writes the secret message, encrypts it and sends it - to Bobby, who in turn decrypts it: - - Alicia Bobby - echo "Love you, honey" > letter - pcp1 -e -r Bobby -I letter -O letter.asc - cat letter.asc | mail bobby@foo.bar - - pcp1 -d -I letter.asc | less - - And that's it. - - Please note the big difference to GPG though: both Alicia AND Bobby have - to enter the passphrase for their secret key! That's the way CURVE25519 - works: you encrypt a message using your secret key and the recipients - public key and the recipient does the opposite, he uses his secret key - and your public key to actually decrypt the message. - - Oh - and if you're wondering why I named them Alicia and Bobby: I was - just sick of Alice and Bob. We're running NSA-free, so we're using other - sample names as well. - -FILES AND PIPES - Pcp behaves like any other unix tool. If not otherwise specified it will - read input from standard input (STDIN) and print output to standard - output (STDOUT). For instance: - - pcp1 -e -O output - - will read the text to be encrypted from standard input, because -I has - not been specified. It works the same with -O: - - pcp1 -e -I myfile - - In this case the encrypted result will be written to standard output. - - Therefore it is possible to use pcp within pipes. Another more realistic - example: - - ssh remote cat file | pcp1 -ez | mailx -s 'as requested' bob@somewhere - - here we encrypt a file symmetrically without downloading it from a - remote ssh server and sending the encrypted result via email to someone. - - The behavior is the same with any other functionality where files are - involved like importing or exporting keys. However, there's one - exception: If the option -X (--password-file) has been used and is set - to -, then this will take precedence over any other possible use of - standard input. So if you want to encrypt something and don't specify an - input file you cannot use -X -, and vice versa. IF you use -X - the - passphrase will be read from standard input, which then can't be used - further for input files elsewhere. Pcp will exit with an error in such a - case. - -INSTALLATION - There are currently no packages available, so pcp has to be compiled - from source. Follow these steps: - - First, you will need libsodium: - - git clone git://github.com/jedisct1/libsodium.git - cd libsodium - ./autogen.sh - ./configure && make check - sudo make install - sudo ldconfig - cd .. - - If you want to have JSON support, you'll need to install the Jansson - library (optional): - - git clone git://github.com/akheron/jansson.git - cd jansson - autoreconf -i - ./configure && make - sudo make install - cd .. - - In order to use the python binding, you need to install the cffi python - package. - - Next, build pcp: - - git clone git://github.com/tlinden/pcp.git - cd pcp - ./configure - sudo make install - cd .. - - Optionally, you might run the unit tests: - - make test - -DOCUMENTATION - To learn how to use pcp, read the manpage: - - man pcp1 - -COPYRIGHT - Copyright (c) 2013-2015 by T.v.Dein - -ADDITIONAL COPYRIGHTS - ZeroMQ Z85 encoding routine - Copyright (c) 2007-2013 iMatix Corporation - Copyright (c) 2009-2011 250bpm s.r.o. - Copyright (c) 2010-2011 Miru Limited - Copyright (c) 2011 VMware, Inc. - Copyright (c) 2012 Spotify AB - - Tarsnap readpass helpers - Copyright 2009 Colin Percival - - jen_hash() hash algorithm - Bob Jenkins, Public Domain. - - UTHASH hashing macros - Copyright (c) 2003-2013, Troy D. Hanson - - Random art image from OpenSSH keygen - Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. - - Comitted by Alexander von Gernler in rev 1.7. - - Every incorporated source code is opensource and licensed under the GPL - as well. - -AUTHORS - *T.v.Dein - -LICENSE - Licensed under the GNU GENERAL PUBLIC LICENSE version 3. - -HOME - The homepage of Pretty Curved Privacy can be found on - http://www.daemon.de/PrettyCurvedPrivacy. The source is on Github: - https://github.com/TLINDEN/pcp - diff --git a/README.md b/README.md new file mode 100644 index 0000000..add15d9 --- /dev/null +++ b/README.md @@ -0,0 +1,187 @@ +# Pretty Curved Privacy + +Pretty Curved Privacy (pcp1) is a commandline utility which can be used +to encrypt files. pcp1 uses eliptc curve cryptography for encryption +(CURVE25519 by Dan J. Bernstein). While CURVE25519 is no worldwide +accepted standard it hasn't been compromised by the NSA - which might be +better, depending on your point of view. + +Caution: since CURVE25519 is no accepted standard, pcp1 has to be +considered as experimental software. In fact, I wrote it just to learn +about the curve and see how it works. + +Beside some differences it works like GNUPG. So, if you already know how +to use gpg, you'll feel almost home. + +# QUICKSTART + +Lets say, Alicia and Bobby want to exchange encrypted messages. Here's +what the've got to do. + +First, both have create a secret key: + + Alicia Bobby + pcp1 -k pcp1 -k + +After entering their name, email address and a passphrase to protect the +key, it will be stored in their vault file (by default ~/.pcpvault). + +Now, both of them have to export the public key, which has to be +imported by the other one. With pcp you can export the public part of +your primary key, but the better solution is to export a derived public +key especially for the recipient: + + Alicia Bobby + pcp1 -p -r Bobby -O alicia.pub pcp1 -p -r Alicia -O bobby.pub + +They've to exchange the public key somehow (which is not my problem at +the moment, use ssh, encrypted mail, whatever). Once exchanged, they +have to import it: + + Alicia Bobby + pcp1 -K -I bobby.pub pcp1 -K -I alicia.pub + +They will see a response as this when done: + + key 0x29A323A2C295D391 added to .pcpvault. + +Now, Alicia finally writes the secret message, encrypts it and sends it +to Bobby, who in turn decrypts it: + + Alicia Bobby + echo "Love you, honey" > letter + pcp1 -e -r Bobby -I letter -O letter.asc + cat letter.asc | mail bobby@foo.bar + + pcp1 -d -I letter.asc | less + +And that's it. + +Please note the big difference to GPG though: both Alicia AND Bobby have +to enter the passphrase for their secret key! That's the way CURVE25519 +works: you encrypt a message using your secret key and the recipients +public key and the recipient does the opposite, he uses his secret key +and your public key to actually decrypt the message. + +Oh - and if you're wondering why I named them Alicia and Bobby: I was +just sick of Alice and Bob. We're running NSA-free, so we're using other +sample names as well. + +# FILES AND PIPES + +Pcp behaves like any other unix tool. If not otherwise specified it will +read input from standard input (STDIN) and print output to standard +output (STDOUT). For instance: + + pcp1 -e -O output + +will read the text to be encrypted from standard input, because -I has +not been specified. It works the same with -O: + + pcp1 -e -I myfile + +In this case the encrypted result will be written to standard output. + +Therefore it is possible to use pcp within pipes. Another more realistic +example: + + ssh remote cat file | pcp1 -ez | mailx -s 'as requested' bob@somewhere + +here we encrypt a file symmetrically without downloading it from a +remote ssh server and sending the encrypted result via email to someone. + +The behavior is the same with any other functionality where files are +involved like importing or exporting keys. However, there's one +exception: If the option -X (--password-file) has been used and is set +to -, then this will take precedence over any other possible use of +standard input. So if you want to encrypt something and don't specify an +input file you cannot use -X -, and vice versa. IF you use -X - the +passphrase will be read from standard input, which then can't be used +further for input files elsewhere. Pcp will exit with an error in such a +case. + +# INSTALLATION + +here are currently no packages available, so pcp has to be compiled +from source. Follow these steps: + +First, you will need libsodium: + + git clone git://github.com/jedisct1/libsodium.git + cd libsodium + ./autogen.sh + ./configure && make check + sudo make install + sudo ldconfig + cd .. + +If you want to have JSON support, you'll need to install the Jansson +library (optional): + + git clone git://github.com/akheron/jansson.git + cd jansson + autoreconf -i + ./configure && make + sudo make install + cd .. + +In order to use the python binding, you need to install the cffi python +package. + +Next, build pcp: + + git clone git://codeberg.org/scip/pcp.git + cd pcp + meson setup build + ninja -C build + sudo ninja -C install + +Optionally, you might run the unit tests: + + make test + +DOCUMENTATION +To learn how to use pcp, read the manpage: + + man pcp1 + +# COPYRIGHT + +Copyright (c) 2013-2015 by T.v.Dein + +## ZeroMQ Z85 encoding routine: + +- Copyright (c) 2007-2013 iMatix Corporation +- Copyright (c) 2009-2011 250bpm s.r.o. +- Copyright (c) 2010-2011 Miru Limited +- Copyright (c) 2011 VMware, Inc. +- Copyright (c) 2012 Spotify AB + +## Tarsnap readpass helpers + +Copyright 2009 Colin Percival + +## jen_hash() hash algorithm + +Bob Jenkins, Public Domain. + +## UTHASH hashing macros + +Copyright (c) 2003-2013, Troy D. Hanson + +# Random art image from OpenSSH keygen + +Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. + +Comitted by Alexander von Gernler in rev 1.7. + + +# AUTHORS + +*T.v.Dein + +# LICENSE + +Licensed under the GNU GENERAL PUBLIC LICENSE version 3. + + diff --git a/README.pod b/README.pod deleted file mode 100644 index ede4cf5..0000000 --- a/README.pod +++ /dev/null @@ -1,217 +0,0 @@ -=begin html - -build status -build status - -=end html - - -=head1 DESCRIPTION - -B (pcp1) is a commandline utility which can -be used to encrypt files. B uses eliptc curve cryptography -for encryption (CURVE25519 by Dan J. Bernstein). While CURVE25519 -is no worldwide accepted standard it hasn't been compromised by -the NSA - which might be better, depending on your point of view. - -B: since CURVE25519 is no accepted standard, B has -to be considered as experimental software. In fact, I wrote it just -to learn about the curve and see how it works. - -Beside some differences it works like B. So, if you already -know how to use gpg, you'll feel almost home. - -=head1 QUICKSTART - -Lets say, Alicia and Bobby want to exchange encrypted messages. -Here's what the've got to do. - -First, both have create a secret key: - - Alicia Bobby - pcp1 -k pcp1 -k - -After entering their name, email address and a passphrase to protect -the key, it will be stored in their B (by default ~/.pcpvault). - -Now, both of them have to export the public key, which has to be -imported by the other one. With B you can export the public -part of your primary key, but the better solution is to export -a derived public key especially for the recipient: - - Alicia Bobby - pcp1 -p -r Bobby -O alicia.pub pcp1 -p -r Alicia -O bobby.pub - -They've to exchange the public key somehow (which is not my -problem at the moment, use ssh, encrypted mail, whatever). Once exchanged, -they have to import it: - - Alicia Bobby - pcp1 -K -I bobby.pub pcp1 -K -I alicia.pub - -They will see a response as this when done: - - key 0x29A323A2C295D391 added to .pcpvault. - -Now, Alicia finally writes the secret message, encrypts it and -sends it to Bobby, who in turn decrypts it: - - Alicia Bobby - echo "Love you, honey" > letter - pcp1 -e -r Bobby -I letter -O letter.asc - cat letter.asc | mail bobby@foo.bar - - pcp1 -d -I letter.asc | less - -And that's it. - -Please note the big difference to B though: both Alicia -AND Bobby have to enter the passphrase for their secret key! -That's the way CURVE25519 works: you encrypt a message using -your secret key and the recipients public key and the recipient -does the opposite, he uses his secret key and your public key -to actually decrypt the message. - -Oh - and if you're wondering why I named them Alicia and Bobby: -I was just sick of Alice and Bob. We're running NSA-free, so we're -using other sample names as well. - -=head1 FILES AND PIPES - -Pcp behaves like any other unix tool. If not otherwise specified -it will read input from standard input (STDIN) and print output -to standard output (STDOUT). For instance: - - pcp1 -e -O output - -will read the text to be encrypted from standard input, because B<-I> -has not been specified. It works the same with B<-O>: - - pcp1 -e -I myfile - -In this case the encrypted result will be written to standard output. - -Therefore it is possible to use pcp within pipes. Another more -realistic example: - - ssh remote cat file | pcp1 -ez | mailx -s 'as requested' bob@somewhere - -here we encrypt a file symmetrically without downloading it from a -remote ssh server and sending the encrypted result via email to -someone. - -The behavior is the same with any other functionality where files are involved -like importing or exporting keys. However, there's one exception: -If the option B<-X> (B<--password-file>) has been used and is set -to B<->, then this will take precedence over any other possible use -of standard input. So if you want to encrypt something and don't -specify an input file you cannot use B<-X ->, and vice versa. IF -you use B<-X -> the passphrase will be read from standard input, which -then can't be used further for input files elsewhere. Pcp will exit -with an error in such a case. - -=head1 INSTALLATION - -There are currently no packages available, so B has to be -compiled from source. Follow these steps: - -First, you will need libsodium: - - git clone git://github.com/jedisct1/libsodium.git - cd libsodium - ./autogen.sh - ./configure && make check - sudo make install - sudo ldconfig - cd .. - -If you want to have JSON support, you'll need to install the -Jansson library (optional): - - git clone git://github.com/akheron/jansson.git - cd jansson - autoreconf -i - ./configure && make - sudo make install - cd .. - -In order to use the python binding, you need to install the -B python package. - -Next, build pcp: - - git clone git://github.com/tlinden/pcp.git - cd pcp - ./configure - sudo make install - cd .. - -Optionally, you might run the unit tests: - - make test - -=head1 DOCUMENTATION - -To learn how to use B, read the manpage: - - man pcp1 - - -=head1 COPYRIGHT - -Copyright (c) 2013-2015 by T.v.Dein - -=head1 ADDITIONAL COPYRIGHTS - -=over - -=item B - - Copyright (c) 2007-2013 iMatix Corporation - Copyright (c) 2009-2011 250bpm s.r.o. - Copyright (c) 2010-2011 Miru Limited - Copyright (c) 2011 VMware, Inc. - Copyright (c) 2012 Spotify AB - -=item B - - Copyright 2009 Colin Percival - -=item B - - Bob Jenkins, Public Domain. - -=item B - - Copyright (c) 2003-2013, Troy D. Hanson - -=item B - - Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. - - Comitted by Alexander von Gernler in rev 1.7. - -=back - -Every incorporated source code is opensource and licensed -under the B as well. - -=head1 AUTHORS - -I> - -=head1 LICENSE - -Licensed under the GNU GENERAL PUBLIC LICENSE version 3. - -=head1 HOME - -The homepage of Pretty Curved Privacy can be found on -http://www.daemon.de/PrettyCurvedPrivacy. The source is -on Github: https://github.com/TLINDEN/pcp - -=cut diff --git a/VERSION b/VERSION index 60a2d3e..267577d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.4.0 \ No newline at end of file +0.4.1 diff --git a/autogen.sh b/autogen.sh deleted file mode 100755 index 1d8a318..0000000 --- a/autogen.sh +++ /dev/null @@ -1,119 +0,0 @@ -#!/bin/sh - -mode=config - -case $1 in - clean) - mode=clean - ;; - gen) - mode=gen - ;; - -h|--help|help|\?) - echo "Usage: $0 [clean|gen]" - exit 1 - ;; -esac - - -if test "$mode" = "gen"; then - # generate the install include file - (echo "#ifndef _HAVE_PCP"; echo "#define _HAVE_PCP"; echo) > include/pcp.h - (echo "#ifdef __cplusplus"; echo "extern \"C\" {"; echo "#endif"; echo) >> include/pcp.h - echo "#include \"pcp/config.h\"" >> include/pcp.h - - ls include/pcp/*.h | sed 's#include/##' | while read include; do - echo "#include \"$include\"" >> include/pcp.h - done - - (echo "#ifdef __cplusplus"; echo "}"; echo "#endif"; echo) >> include/pcp.h - (echo; echo "#endif") >> include/pcp.h - - - # generate the version file - maj=`egrep "#define PCP_VERSION_MAJOR" include/pcp/version.h | awk '{print $3}'` - min=`egrep "#define PCP_VERSION_MINOR" include/pcp/version.h | awk '{print $3}'` - pat=`egrep "#define PCP_VERSION_PATCH" include/pcp/version.h | awk '{print $3}'` - echo -n "$maj.$min.$pat" > VERSION - - # generate the manpage - echo "=head1 NAME - -Pretty Curved Privacy - File encryption using eliptic curve cryptography. - -=head1 SYNOPSIS - -" > man/pcp1.pod - cat src/usage.txt | sed "s/^/ /g" >> man/pcp1.pod - cat man/options.pod >> man/pcp1.pod - cat man/pcp.pod >> man/pcp1.pod - cat man/details.pod >> man/pcp1.pod - cat man/footer.pod >> man/pcp1.pod - - pod2man -r "PCP `cat VERSION`" -c "USER CONTRIBUTED DOCUMENTATION" man/pcp1.pod > man/pcp1.1 - pod2html man/pcp1.pod > man/pcp1.html - - # generate the top level readme - cat man/badges man/pcp.pod man/install.pod man/footer.pod > README.pod - pod2text README.pod > README - - # generate usage.h - (cd src && ./usage.sh) - - # generate pypcp types - cd bindings/py - ./gencffi.pl ../../include/pcp/*.h > pypcp/raw.py - cd - - - exit -fi - - - -if test "$mode" = "config"; then - mkdir -p ./config - - lt=libtoolize - case `uname` in Darwin*) lt=glibtoolize;; esac - - if ! command -v $lt >/dev/null 2>&1 ; then - echo "could not find $lt." 1>&2 - exit 1 - fi - - if ! command -v autoreconf >/dev/null 2>&1; then - echo "could not find autoreconf." 1>&2 - exit 1 - fi - - autoreconf --install --force --verbose -I config -fi - - -# -# normal autogen stuff - -cat < clean.sh -#!/bin/sh -find . -name Makefile -exec rm {} \; > /dev/null 2>&1 -find . -name Makefile.in -exec rm {} \; > /dev/null 2>&1 -find . -name "*~" -exec rm {} \; > /dev/null 2>&1 -find . -name config.h -exec rm {} \; > /dev/null 2>&1 -find . -name "stamp*" -exec rm {} \; > /dev/null 2>&1 -find . -name .deps -exec rm -rf {} \; > /dev/null 2>&1 -find . -name .libs -exec rm -rf {} \; > /dev/null 2>&1 -find . -name .o -exec rm -rf {} \; > /dev/null 2>&1 -find . -name .lo -exec rm -rf {} \; > /dev/null 2>&1 -find . -name .pyc -exec rm -rf {} \; > /dev/null 2>&1 -find . -name .dirstamp -exec rm -rf {} \; > /dev/null 2>&1 -rm -rf aclocal.m4 libtool configure config.* config autom4te.cache tests/test* tests/v* tests/stresstest/* libpcp/libpcp1.pc -rm clean.sh -EOF - -chmod 700 clean.sh - - -rm -rf include/pcp/config.h.in~ libpcp/stamp-h1 autom4te.cache - -sleep 1 -touch Makefile.in configure */Makefile.in diff --git a/configure.ac b/configure.ac deleted file mode 100755 index 47e6c75..0000000 --- a/configure.ac +++ /dev/null @@ -1,383 +0,0 @@ -# -*-sh-*- -# -# This file is part of Pretty Curved Privacy (pcp1). -# -# Copyright (C) 2013-2015 T.Linden. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -# You can contact me by mail: . -# - -AC_PREREQ(2.61) - -define([pcpversion], esyscmd([sh -c "cat VERSION"]))dnl -AC_INIT([pcp], [pcpversion], [pcp@daemon.de]) -#AC_INIT(pcp, `cat VERSION`) -AC_CONFIG_AUX_DIR(config) -AC_CONFIG_MACRO_DIR(config) - -AC_CONFIG_HEADER(include/pcp/config.h) -AM_INIT_AUTOMAKE([subdir-objects]) -LT_INIT - -ORIG_CFLAGS="${CFLAGS:-none}" - - -# Checks for programs -AC_PROG_CXX -AC_PROG_CXXCPP - -AC_PROG_CC -AM_PROG_CC_C_O -AC_PROG_LIBTOOL -AC_PROG_SED -AC_PROG_AWK -AC_PROG_INSTALL - -# remove flags set by AC_PROG_CC (duplicates and/or invalid for clang) -# FIXME: why did I do this?! -#CFLAGS="" -#CXXFLAGS="" - - -# Host speciffic checks -AC_CANONICAL_HOST - -# Checks for header files. -AC_HEADER_STDC -AC_CHECK_HEADERS(errno.h err.h stdlib.h string.h unistd.h stdio.h getopt.h\ - limits.h stddef.h stdint.h sys/types.h sys/stat.h \ - termios.h arpa/inet.h netinet/in.h wctype.h) - -AC_TYPE_SIZE_T - -# Checks for library functions. -AC_CHECK_FUNCS( \ - arc4random_buf \ - arc4random \ - fread \ - fopen \ - free \ - fwrite \ - fseek \ - ftruncate \ - fprintf \ - isatty \ - malloc \ - memset \ - memcpy \ - mmap \ - perror \ - posix_memalign \ - setrlimit \ - strnlen \ - strnstr \ - strlen \ - strtol \ - sizeof \ - tcgetattr \ - umask \ - towlower \ - getopt_long \ - vasprintf -) - -cross_compile="no" -AC_MSG_CHECKING([compiler and flags for sanity]) -AC_RUN_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ exit(0); ]])], - [ AC_MSG_RESULT([yes]) ], - [ - AC_MSG_RESULT([no]) - AC_MSG_ERROR([*** compiler cannot create working executables, check config.log ***]) - ], - [ - AC_MSG_WARN([cross compiling: not checking compiler sanity]) - [cross_compile="yes"] - ] -) - -_havenacl=no -_ldlib="" -_have_json=no - -AC_ARG_WITH([libsodium], - [AS_HELP_STRING([--with-libsodium], - [Specify libsodium prefix])], - [search_libsodium="yes"], - []) - -if test "x$search_libsodium" = "xyes"; then - if test -r "${with_libsodium}/include/sodium.h"; then - CFLAGS="-I${with_libsodium}/include ${CFLAGS}" - LDFLAGS="-L${with_libsodium}/lib ${LDFLAGS}" - _havenacl=yes - _ldlib="${with_libsodium}/lib" - fi -fi - -AC_ARG_WITH([libsodium-include-dir], - [AS_HELP_STRING([--with-libsodium-include-dir], - [Specify libsodium include prefix])], - [search_libsodium_include="yes"], - []) - -if test "x$search_libsodium_include" = "xyes"; then - if test -r "${with_libsodium_include_dir}/sodium.h"; then - CFLAGS="-I${with_libsodium_include_dir} ${CFLAGS}" - _havenacl=yes - fi -fi - -AC_ARG_WITH([libsodium_lib_dir], - [AS_HELP_STRING([--with-libsodium-lib-dir], - [Specify libsodium library prefix])], - [search_libsodium_lib="yes"], - []) - -if test "x$search_libsodium_lib" = "xyes"; then - if test -r "${with_libsodium_lib_dir}/libsodium.dylib" -o -r "${with_libsodium_lib_dir}/libsodium.so" -o -r "${with_libsodium_lib_dir}/libsodium.a"; then - LDFLAGS="-L${with_libsodium_lib_dir} ${LDFLAGS}" - _havenacl=yes - _ldlib="${with_libsodium_lib_dir}" - fi -fi - -if test "x${_havenacl}" = "xno"; then - AC_MSG_CHECKING([pkg-config for libsodium]) - if pkg-config --exists libsodium; then - # found it - LDFLAGS="`pkg-config --libs libsodium` ${LDFLAGS}" - CFLAGS="`pkg-config --cflags libsodium` ${CFLAGS}" - _ldlib=`pkg-config --libs libsodium | cut -d ' ' -f 1 | cut -d L -f 2` - _havenacl=yes - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - fi -fi - -if test "x${_havenacl}" != "xno" -a "x$cross_compile" = "xno"; then - LIBS="-lsodium" # gcc - export LDFLAGS="$LDFLAGS" - export CFLAGS="$CFLAGS" - export LIBS="$LIBS" - AC_MSG_CHECKING([libsodium version compatible]) - AC_RUN_IFELSE([ - AC_LANG_PROGRAM([[ -#include - ]],[[ - if (sodium_library_version_major() >= 7) { exit(0); } - else { exit(1); } - ]])], - [ - AC_MSG_RESULT([yes]) - ], - [ - AC_MSG_ERROR([no, libsodium too old. please update your libsodium installation. or maybe the path in "$LDFLAGS" is not in LD_LIBRARY_PATH?]) - ] - ) -fi - - -AC_ARG_WITH([json], - [AS_HELP_STRING([--with-json], - [enable JSON support])], - [search_json="yes"], - []) - -if test "x$search_json" = "xyes"; then - # use pkg only - # FIXME: search - _have_json="yes" - LDFLAGS="$LDFLAGS -ljansson" - CFLAGS="$CFLAGS -DHAVE_JSON=1" -fi - -AM_CONDITIONAL([BUILDJSON], [test "x$_have_json" = "xyes"]) - - -# Check for some target-specific stuff -case "$host" in - *aix*) - # libm is required as well - CFLAGS="$CFLAGS -D_AIX_SOURCE=1" - LDFLAGS="$LDFLAGS -lm" - ;; - *-*-android*) ;; - *-*-cygwin*) ;; - *-*-dgux*) ;; - *-*-darwin*) ;; - *-*-dragonfly*) ;; - *-*-haiku*) ;; - *-*-hpux*) ;; - *-*-irix5*) ;; - *-*-irix6*) ;; - *-*-k*bsd*-gnu | *-*-kopensolaris*-gnu) ;; - *-*-linux*) ;; - *-*-netbsd*) ;; - *-*-freebsd*) - # ports install to /usr/local by default, check - if test -d "/usr/local/lib" -a -d "/usr/local/include"; then - CFLAGS="$CFLAGS -I/usr/local/include" - LDFLAGS="$LDFLAGS -L/usr/local/lib" - fi - ;; - *-*-bsdi*) ;; - *-next-*) ;; - *-*-openbsd*) ;; - *-*-solaris*) ;; - *-*-sunos4*) ;; - *-ncr-sysv*) ;; - *-sni-sysv*) ;; - *-*-sysv4.2*) ;; - *-*-sysv5*) ;; - *-*-sysv*) ;; - *-*-sco*) ;; - *-*-unicos*) ;; - *-dec-osf*) ;; - *-*-nto-qnx*) ;; - *-*-ultrix*) ;; - *-*-lynxos) ;; -esac -AC_CHECK_LIB(sodium, sodium_init, , [AC_MSG_ERROR([cannot link with -lsodium, install libsodium.])]) - -if test -n "$_ldlib"; then - export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${_ldlib}" -fi - -if test "$cross_compile" = "no"; then -AC_MSG_CHECKING([is libsodium compiled correctly]) -AC_RUN_IFELSE([ -AC_LANG_PROGRAM([[ -#include -#include -#if crypto_box_PUBLICKEYBYTES != 32 || crypto_box_SECRETKEYBYTES != 32 || crypto_sign_PUBLICKEYBYTES != 32 || crypto_sign_PUBLICKEYBYTES != 32 -# error "libsodium not built correctly" -#endif -]],[[exit(0);]])], - [ - AC_MSG_RESULT([yes]) - ], - [ - AC_MSG_ERROR([no. please check your libsodium installation, consider re-installing]) - ] -) -fi - -# prepare FLAGS -CFLAGS="$CFLAGS -Werror -Wextra -Wall" - -AC_ARG_ENABLE([debug], - AS_HELP_STRING([--disable-debug], [Disable debugging])) - -AS_IF([test "x$enable_debug" != "xno"], [ - CFLAGS="$CFLAGS -g -DDEBUG" - enable_debug="yes" -]) - -AC_ARG_ENABLE([optimize], - AS_HELP_STRING([--disable-optimize], [Disable optimization])) - -AS_IF([test "x$enable_optimize" != "xno"], [ - case $enable_optimize in - -O*) - CFLAGS="$CFLAGS $enable_optimize" - enable_optimize="$enable_optimize" - ;; - *) - CFLAGS="$CFLAGS -O2" - enable_optimize="-O2" - ;; - esac -]) - - -CXXFLAGS="$CFLAGS" - -# FIXME: check for libm -LIBS="$LIBS -lm" - -# conditionals for bindings and stuff - -# c++ -AC_ARG_ENABLE([cpp-binding], - [AS_HELP_STRING([--disable-cpp-binding], - [Disable C++ binding])], - ) - -AS_IF([test "x$enable_cpp_binding" != "xno"], [ - enable_cpp_binding=yes - ]) - -AM_CONDITIONAL([BUILDCPP], [test "x$enable_cpp_binding" != "xno"]) - -# py -AC_ARG_ENABLE([python-binding], - [AS_HELP_STRING([--enable-python-binding], - [Enable python binding]) - ], - [python="yes"], - []) - -if test "x$python" = "xyes"; then - if ! python -c "import cffi" > /dev/null 2>&1; then - python="no" - AC_MSG_ERROR([python or cffi is not installed]) - fi -else - python="no" -fi - -AM_CONDITIONAL([BUILDPY], [test "x$python" = "xyes"]) - - - -AC_SUBST(PACKAGE_VERSION) - -# Specify output files -AC_CONFIG_FILES([Makefile include/Makefile libpcp/Makefile src/Makefile man/Makefile \ - tests/Makefile libpcp/libpcp1.pc bindings/cpp/Makefile bindings/py/Makefile]) - - - - -AC_OUTPUT - -AC_MSG_RESULT([ - Build configured for $PACKAGE $VERSION: - CC: ${CC} - CFLAGS: ${CFLAGS} - CXX: ${CXX} - CXXFLAGS: ${CXXFLAGS} - LDFLAGS: ${LDFLAGS} - LIBS: ${LIBS} - DEBUG: ${enable_debug} - optimize: ${enable_optimize} - - prefix: ${prefix} - libdir: ${libdir} - includedir: ${includedir} - - target platform: ${host} - cross compile: ${cross_compile} - - build python binding: ${python} - build c++ binding: ${enable_cpp_binding} - - json support: ${_have_json} - - Type 'make' to build, 'make install' to install. - To execute unit tests, type 'make test'. -]) diff --git a/libpcp/Makefile.am b/libpcp/Makefile.am deleted file mode 100644 index 3a331cf..0000000 --- a/libpcp/Makefile.am +++ /dev/null @@ -1,38 +0,0 @@ -# -# This file is part of Pretty Curved Privacy (pcp1). -# -# Copyright (C) 2013 T.Linden. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -# You can contact me by mail: . -# -AM_CFLAGS = -I../include/pcp - -lib_LTLIBRARIES = libpcp1.la - -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = libpcp1.pc - -libpcp1_la_SOURCES = platform.c mem.c version.c \ - context.c z85.c zmq_z85.c key.c randomart.c \ - vault.c jenhash.c readpass.c \ - crypto.c ed.c keyhash.c scrypt.c \ - util.c buffer.c mgmt.c keysig.c pcpstream.c - -include_HEADERS = ../include/pcp.h - -libpcp1_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ diff --git a/libpcp/config.h.in b/libpcp/config.h.in new file mode 100644 index 0000000..9d142bd --- /dev/null +++ b/libpcp/config.h.in @@ -0,0 +1,17 @@ +/* platform.h.in. Generated from configure.ac by autoheader. */ + +#mesondefine HAVE_SODIUM +#mesondefine HAVE_JSON + +#mesondefine HAVE_GETOPT +#mesondefine HAVE_GETOPT_LONG +#mesondefine HAVE_SETRLIMIT +#mesondefine HAVE_VASPRINTF +#mesondefine HAVE_STRNLEN + +#define PACKAGE "pcp" + +#define VERSION "@VERSION@" + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const diff --git a/include/Makefile.am b/libpcp/include/Makefile.am similarity index 100% rename from include/Makefile.am rename to libpcp/include/Makefile.am diff --git a/include/pcp.h b/libpcp/include/pcp.h similarity index 100% rename from include/pcp.h rename to libpcp/include/pcp.h diff --git a/include/pcp/buffer.h b/libpcp/include/pcp/buffer.h similarity index 100% rename from include/pcp/buffer.h rename to libpcp/include/pcp/buffer.h diff --git a/include/pcp/config.h.in b/libpcp/include/pcp/config.h.in similarity index 100% rename from include/pcp/config.h.in rename to libpcp/include/pcp/config.h.in diff --git a/include/pcp/context.h b/libpcp/include/pcp/context.h similarity index 100% rename from include/pcp/context.h rename to libpcp/include/pcp/context.h diff --git a/include/pcp/crypto.h b/libpcp/include/pcp/crypto.h similarity index 100% rename from include/pcp/crypto.h rename to libpcp/include/pcp/crypto.h diff --git a/include/pcp/defines.h b/libpcp/include/pcp/defines.h similarity index 100% rename from include/pcp/defines.h rename to libpcp/include/pcp/defines.h diff --git a/include/pcp/ed.h b/libpcp/include/pcp/ed.h similarity index 100% rename from include/pcp/ed.h rename to libpcp/include/pcp/ed.h diff --git a/include/pcp/getpass.h b/libpcp/include/pcp/getpass.h similarity index 100% rename from include/pcp/getpass.h rename to libpcp/include/pcp/getpass.h diff --git a/include/pcp/jenhash.h b/libpcp/include/pcp/jenhash.h similarity index 100% rename from include/pcp/jenhash.h rename to libpcp/include/pcp/jenhash.h diff --git a/include/pcp/key.h b/libpcp/include/pcp/key.h similarity index 100% rename from include/pcp/key.h rename to libpcp/include/pcp/key.h diff --git a/include/pcp/keyhash.h b/libpcp/include/pcp/keyhash.h similarity index 100% rename from include/pcp/keyhash.h rename to libpcp/include/pcp/keyhash.h diff --git a/include/pcp/keysig.h b/libpcp/include/pcp/keysig.h similarity index 100% rename from include/pcp/keysig.h rename to libpcp/include/pcp/keysig.h diff --git a/include/pcp/mem.h b/libpcp/include/pcp/mem.h similarity index 100% rename from include/pcp/mem.h rename to libpcp/include/pcp/mem.h diff --git a/include/pcp/mgmt.h b/libpcp/include/pcp/mgmt.h similarity index 85% rename from include/pcp/mgmt.h rename to libpcp/include/pcp/mgmt.h index 964f153..fe24e1c 100644 --- a/include/pcp/mgmt.h +++ b/libpcp/include/pcp/mgmt.h @@ -27,49 +27,49 @@ #define _HAVE_PCP_MGMT_H #if defined __linux__ || defined __GNU__ || defined __GLIBC__ -# ifndef _DEFAULT_SOURCE -# define _DEFAULT_SOURCE 1 -# endif +#ifndef _DEFAULT_SOURCE +#define _DEFAULT_SOURCE 1 +#endif # -# ifndef _XOPEN_SOURCE -# define _XOPEN_SOURCE 1 -# endif +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 1 +#endif # -# ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -# endif +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif # -# ifndef __USE_XOPEN -# define __USE_XOPEN 1 -# endif +#ifndef __USE_XOPEN +#define __USE_XOPEN 1 +#endif # #else -# define _BSD_SOURCE 1 +#define _BSD_SOURCE 1 #endif #include -#include #include +#include #include -#ifdef HAVE_JSON +// #ifdef HAVE_JSON +#ifndef JANSSON_H #include #endif +#include "buffer.h" +#include "context.h" #include "defines.h" -#include "platform.h" -#include "structs.h" -#include "mem.h" #include "ed.h" #include "key.h" #include "keysig.h" -#include "buffer.h" +#include "mem.h" +#include "platform.h" #include "scrypt.h" -#include "context.h" +#include "structs.h" /* key management api, export, import, and stuff */ - /** * \defgroup PubKeyExport KEYEXPORT * @{ @@ -77,10 +77,6 @@ Functions to export and import keys in various formats. */ - - - - /** RFC4880 alike public key export with some modifications. (Refer to the INTERNALS section of the pcp(1) manual page for details. @@ -90,11 +86,9 @@ \return the function returns a Buffer object containing the binary blob in the format described above. - + */ -Buffer *pcp_export_rfc_pub (PCPCTX *ptx, pcp_key_t *sk); - - +Buffer *pcp_export_rfc_pub(PCPCTX *ptx, pcp_key_t *sk); /** Export a public key in PBP format. Export a public key in the format described at @@ -110,7 +104,8 @@ Buffer *pcp_export_pbp_pub(pcp_key_t *sk); /** Export secret key. - Export a secret key. (refer to the INTERNALS section of the pcp(1) manual page for details). + Export a secret key. (refer to the INTERNALS section of the pcp(1) manual + page for details). \param[in] ptx context. @@ -135,7 +130,8 @@ Buffer *pcp_export_secret(PCPCTX *ptx, pcp_key_t *sk, char *passphrase); \return the function returns a Buffer object containing the binary blob containing a JSON string. */ -Buffer *pcp_export_json_pub(PCPCTX *ptx, pcp_key_t *sk, byte *sig, size_t siglen); +Buffer *pcp_export_json_pub(PCPCTX *ptx, pcp_key_t *sk, byte *sig, + size_t siglen); /** Export secret key in JSON format @@ -148,7 +144,8 @@ Buffer *pcp_export_json_pub(PCPCTX *ptx, pcp_key_t *sk, byte *sig, size_t siglen \return the function returns a Buffer object containing the binary blob containing a JSON string. */ -Buffer *pcp_export_json_secret(PCPCTX *ptx, pcp_key_t *sk, byte *nonce, byte *cipher, size_t clen); +Buffer *pcp_export_json_secret(PCPCTX *ptx, pcp_key_t *sk, byte *nonce, + byte *cipher, size_t clen); /** Convert secret key struct into JSON struct @@ -157,7 +154,7 @@ Buffer *pcp_export_json_secret(PCPCTX *ptx, pcp_key_t *sk, byte *nonce, byte *ci \return returns a json_t structure (see libjansson docs for details) */ -json_t *pcp_sk2json(pcp_key_t *sk, byte *sig,size_t siglen); +json_t *pcp_sk2json(pcp_key_t *sk, byte *sig, size_t siglen); /** Convert public key struct into JSON struct @@ -179,14 +176,19 @@ pcp_ks_bundle_t *pcp_import_pub_rfc(PCPCTX *ptx, Buffer *blob); pcp_ks_bundle_t *pcp_import_pub_pbp(PCPCTX *ptx, Buffer *blob); /* import secret key */ -pcp_key_t *pcp_import_binsecret(PCPCTX *ptx, byte *raw, size_t rawsize, char *passphrase); -pcp_key_t *pcp_import_secret(PCPCTX *ptx, byte *raw, size_t rawsize, char *passphrase); -pcp_key_t *pcp_import_secret_native(PCPCTX *ptx, Buffer *cipher, char *passphrase); +pcp_key_t *pcp_import_binsecret(PCPCTX *ptx, byte *raw, size_t rawsize, + char *passphrase); +pcp_key_t *pcp_import_secret(PCPCTX *ptx, byte *raw, size_t rawsize, + char *passphrase); +pcp_key_t *pcp_import_secret_native(PCPCTX *ptx, Buffer *cipher, + char *passphrase); /* helpers */ int _check_keysig_h(PCPCTX *ptx, Buffer *blob, rfc_pub_sig_h *h); -int _check_hash_keysig(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t *sk); -int _check_sigsubs(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, rfc_pub_sig_s *subheader); +int _check_hash_keysig(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, + pcp_keysig_t *sk); +int _check_sigsubs(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, + rfc_pub_sig_s *subheader); #endif // _HAVE_PCP_MGMT_H diff --git a/include/pcp/pcpstream.h b/libpcp/include/pcp/pcpstream.h similarity index 100% rename from include/pcp/pcpstream.h rename to libpcp/include/pcp/pcpstream.h diff --git a/include/pcp/platform.h b/libpcp/include/pcp/platform.h similarity index 100% rename from include/pcp/platform.h rename to libpcp/include/pcp/platform.h diff --git a/include/pcp/plist.h b/libpcp/include/pcp/plist.h similarity index 100% rename from include/pcp/plist.h rename to libpcp/include/pcp/plist.h diff --git a/include/pcp/randomart.h b/libpcp/include/pcp/randomart.h similarity index 100% rename from include/pcp/randomart.h rename to libpcp/include/pcp/randomart.h diff --git a/include/pcp/readpass.h b/libpcp/include/pcp/readpass.h similarity index 100% rename from include/pcp/readpass.h rename to libpcp/include/pcp/readpass.h diff --git a/include/pcp/scrypt.h b/libpcp/include/pcp/scrypt.h similarity index 100% rename from include/pcp/scrypt.h rename to libpcp/include/pcp/scrypt.h diff --git a/include/pcp/structs.h b/libpcp/include/pcp/structs.h similarity index 100% rename from include/pcp/structs.h rename to libpcp/include/pcp/structs.h diff --git a/include/pcp/uthash.h b/libpcp/include/pcp/uthash.h similarity index 100% rename from include/pcp/uthash.h rename to libpcp/include/pcp/uthash.h diff --git a/include/pcp/util.h b/libpcp/include/pcp/util.h similarity index 100% rename from include/pcp/util.h rename to libpcp/include/pcp/util.h diff --git a/include/pcp/vault.h b/libpcp/include/pcp/vault.h similarity index 100% rename from include/pcp/vault.h rename to libpcp/include/pcp/vault.h diff --git a/include/pcp/version.h b/libpcp/include/pcp/version.h similarity index 100% rename from include/pcp/version.h rename to libpcp/include/pcp/version.h diff --git a/include/pcp/z85.h b/libpcp/include/pcp/z85.h similarity index 100% rename from include/pcp/z85.h rename to libpcp/include/pcp/z85.h diff --git a/include/pcp/zmq_z85.h b/libpcp/include/pcp/zmq_z85.h similarity index 100% rename from include/pcp/zmq_z85.h rename to libpcp/include/pcp/zmq_z85.h diff --git a/libpcp/key.c b/libpcp/key.c index 4e46dcc..b8e76ce 100644 --- a/libpcp/key.c +++ b/libpcp/key.c @@ -19,7 +19,6 @@ You can contact me by mail: . */ - #include "key.h" #include "context.h" @@ -36,10 +35,10 @@ byte *pcp_derivekey(PCPCTX *ptx, char *passphrase, byte *nonce) { byte *scrypted = pcp_scrypt(ptx, passphrase, plen, nonce, LNONCE); /* make a hash from the scrypt() result */ - crypto_hash_sha256(key, (byte*)scrypted, 64); + crypto_hash_sha256(key, (byte *)scrypted, 64); /* turn the 32byte hash into a secret key */ - key[0] &= 248; + key[0] &= 248; key[31] &= 127; key[31] |= 64; @@ -48,7 +47,6 @@ byte *pcp_derivekey(PCPCTX *ptx, char *passphrase, byte *nonce) { return key; } - char *pcp_getkeyid(pcp_key_t *k) { uint32_t s, p; p = jen_hash(k->pub, LBOXPUB, JEN_PSALT); @@ -68,7 +66,8 @@ char *pcp_getpubkeyid(pcp_pubkey_t *k) { return id; } -void pcp_keypairs(byte *msk, byte *mpk, byte *csk, byte *cpk, byte *esk, byte *epk) { +void pcp_keypairs(byte *msk, byte *mpk, byte *csk, byte *cpk, byte *esk, + byte *epk) { /* generate keypairs from random seed */ byte *ms = urmalloc(32); byte *ss = urmalloc(32); @@ -82,7 +81,7 @@ void pcp_keypairs(byte *msk, byte *mpk, byte *csk, byte *cpk, byte *esk, byte *e /* curve25519 secret key */ memcpy(csk, cs, 32); - csk[0] &= 248; + csk[0] &= 248; csk[31] &= 63; csk[31] |= 64; @@ -94,7 +93,7 @@ void pcp_keypairs(byte *msk, byte *mpk, byte *csk, byte *cpk, byte *esk, byte *e ucfree(cs, 32); } -pcp_key_t * pcpkey_new () { +pcp_key_t *pcpkey_new() { byte *mp = ucmalloc(LEDPUB); byte *ms = ucmalloc(LEDSEC); byte *sp = ucmalloc(LEDPUB); @@ -107,22 +106,22 @@ pcp_key_t * pcpkey_new () { /* fill in our struct */ pcp_key_t *key = urmalloc(sizeof(pcp_key_t)); - memcpy (key->masterpub, mp, LEDPUB); - memcpy (key->mastersecret, ms, LEDSEC); - memcpy (key->pub, cp, LBOXPUB); - memcpy (key->secret, cs, LBOXSEC); - memcpy (key->edpub, sp, LEDPUB); - memcpy (key->edsecret, ss, LEDSEC); + memcpy(key->masterpub, mp, LEDPUB); + memcpy(key->mastersecret, ms, LEDSEC); + memcpy(key->pub, cp, LBOXPUB); + memcpy(key->secret, cs, LBOXSEC); + memcpy(key->edpub, sp, LEDPUB); + memcpy(key->edsecret, ss, LEDSEC); char *id = pcp_getkeyid(key); - memcpy (key->id, id, 17); + memcpy(key->id, id, 17); free(id); key->ctime = (long)time(0); key->version = PCP_KEY_VERSION; - key->serial = arc4random(); - key->type = PCP_KEY_TYPE_SECRET; + key->serial = arc4random(); + key->type = PCP_KEY_TYPE_SECRET; key->owner[0] = '\0'; key->mail[0] = '\0'; @@ -138,7 +137,7 @@ pcp_key_t * pcpkey_new () { return key; } -byte * pcp_gennonce() { +byte *pcp_gennonce() { byte *nonce = ucmalloc(LNONCE); arc4random_buf(nonce, LNONCE); return nonce; @@ -150,13 +149,13 @@ void pcpkey_setowner(pcp_key_t *key, char *owner, char *mail) { } pcp_key_t *pcpkey_encrypt(PCPCTX *ptx, pcp_key_t *key, char *passphrase) { - if(key->nonce[0] == 0) { + if (key->nonce[0] == 0) { byte *nonce = pcp_gennonce(); - memcpy (key->nonce, nonce, LNONCE); + memcpy(key->nonce, nonce, LNONCE); ucfree(nonce, LNONCE); } - byte *encryptkey = pcp_derivekey(ptx, passphrase, key->nonce); + byte *encryptkey = pcp_derivekey(ptx, passphrase, key->nonce); byte *encrypted; size_t es; @@ -166,20 +165,20 @@ pcp_key_t *pcpkey_encrypt(PCPCTX *ptx, pcp_key_t *key, char *passphrase) { buffer_add(both, key->edsecret, LEDSEC); buffer_add(both, key->secret, LBOXSEC); - es = pcp_sodium_mac(&encrypted, buffer_get(both), buffer_size(both), key->nonce, encryptkey); + es = pcp_sodium_mac(&encrypted, buffer_get(both), buffer_size(both), + key->nonce, encryptkey); buffer_free(both); sfree(encryptkey); - if(es == LSEC) { + if (es == LSEC) { /* success */ memcpy(key->encrypted, encrypted, LSEC); ucfree(encrypted, es); memset(key->secret, 0, LBOXSEC); memset(key->edsecret, 0, LEDSEC); memset(key->mastersecret, 0, LEDSEC); - } - else { + } else { fatal(ptx, "failed to encrypt the secret key!\n"); ucfree(encrypted, es); ucfree(key, sizeof(pcp_key_t)); @@ -190,23 +189,23 @@ pcp_key_t *pcpkey_encrypt(PCPCTX *ptx, pcp_key_t *key, char *passphrase) { } pcp_key_t *pcpkey_decrypt(PCPCTX *ptx, pcp_key_t *key, char *passphrase) { - byte *encryptkey = pcp_derivekey(ptx, passphrase, key->nonce); + byte *encryptkey = pcp_derivekey(ptx, passphrase, key->nonce); byte *decrypted = ucmalloc(LSEC - crypto_secretbox_MACBYTES); size_t es; - - es = pcp_sodium_verify_mac(&decrypted, key->encrypted, LSEC, key->nonce, encryptkey); + + es = pcp_sodium_verify_mac(&decrypted, key->encrypted, LSEC, key->nonce, + encryptkey); sfree(encryptkey); - if(es == 0) { + if (es == 0) { /* success */ memcpy(key->mastersecret, decrypted, LEDSEC); - memcpy(key->edsecret, decrypted + LEDSEC, LEDSEC); + memcpy(key->edsecret, decrypted + LEDSEC, LEDSEC); memcpy(key->secret, decrypted + LEDSEC + LEDSEC, LBOXSEC); ucfree(decrypted, LEDSEC + LEDSEC + LBOXSEC); - } - else { + } else { fatal(ptx, "failed to decrypt the secret key (got %d, expected 32)!\n", es); ucfree(decrypted, LEDSEC + LEDSEC + LBOXSEC); return NULL; @@ -216,7 +215,7 @@ pcp_key_t *pcpkey_decrypt(PCPCTX *ptx, pcp_key_t *key, char *passphrase) { } pcp_pubkey_t *pcpkey_pub_from_secret(pcp_key_t *key) { - pcp_pubkey_t *pub = urmalloc(sizeof (pcp_pubkey_t)); + pcp_pubkey_t *pub = urmalloc(sizeof(pcp_pubkey_t)); memcpy(pub->masterpub, key->masterpub, LEDPUB); memcpy(pub->pub, key->pub, LBOXPUB); memcpy(pub->edpub, key->edpub, LEDSEC); @@ -224,9 +223,9 @@ pcp_pubkey_t *pcpkey_pub_from_secret(pcp_key_t *key) { memcpy(pub->mail, key->mail, 255); memcpy(pub->id, key->id, 17); pub->version = key->version; - pub->type = PCP_KEY_TYPE_PUBLIC; - pub->ctime = key->ctime; - pub->serial = key->serial; + pub->type = PCP_KEY_TYPE_PUBLIC; + pub->ctime = key->ctime; + pub->serial = key->serial; return pub; } @@ -252,7 +251,6 @@ byte *pcpkey_getchecksum(pcp_key_t *k) { return hash; } - void pcp_pubkeyblob(Buffer *b, pcp_pubkey_t *k) { buffer_add(b, k->masterpub, LEDPUB); buffer_add(b, k->pub, LBOXPUB); @@ -286,8 +284,8 @@ void pcp_seckeyblob(Buffer *b, pcp_key_t *k) { } pcp_key_t *pcp_blob2key(Buffer *b) { - pcp_key_t *k = ucmalloc(sizeof(pcp_key_t)); - + pcp_key_t *k = ucmalloc(sizeof(pcp_key_t)); + buffer_get_chunk(b, k->masterpub, LEDPUB); buffer_get_chunk(b, k->mastersecret, LEDSEC); buffer_get_chunk(b, k->pub, LBOXPUB); @@ -300,17 +298,17 @@ pcp_key_t *pcp_blob2key(Buffer *b) { buffer_get_chunk(b, k->mail, 255); buffer_get_chunk(b, k->id, 17); - k->type = buffer_get8(b); - k->ctime = buffer_get64na(b); - k->version = buffer_get32na(b); - k->serial = buffer_get32na(b); + k->type = buffer_get8(b); + k->ctime = buffer_get64na(b); + k->version = buffer_get32na(b); + k->serial = buffer_get32na(b); return k; } pcp_pubkey_t *pcp_blob2pubkey(Buffer *b) { - pcp_pubkey_t *k = ucmalloc(sizeof(pcp_key_t)); - + pcp_pubkey_t *k = ucmalloc(sizeof(pcp_key_t)); + buffer_get_chunk(b, k->masterpub, LEDPUB); buffer_get_chunk(b, k->pub, LBOXPUB); buffer_get_chunk(b, k->edpub, LEDPUB); @@ -318,56 +316,62 @@ pcp_pubkey_t *pcp_blob2pubkey(Buffer *b) { buffer_get_chunk(b, k->mail, 255); buffer_get_chunk(b, k->id, 17); - k->type = buffer_get8(b); - k->ctime = buffer_get64na(b); - k->version = buffer_get32na(b); - k->serial = buffer_get32na(b); - k->valid = buffer_get8(b); + k->type = buffer_get8(b); + k->ctime = buffer_get64na(b); + k->version = buffer_get32na(b); + k->serial = buffer_get32na(b); + k->valid = buffer_get8(b); return k; } Buffer *pcp_keyblob(void *k, int type) { - if(type == PCP_KEY_TYPE_PUBLIC) { + if (type == PCP_KEY_TYPE_PUBLIC) { Buffer *b = buffer_new(PCP_RAW_PUBKEYSIZE, "bp"); pcp_pubkeyblob(b, (pcp_pubkey_t *)k); return b; - } - else { + } else { Buffer *b = buffer_new(PCP_RAW_KEYSIZE, "bs"); pcp_seckeyblob(b, (pcp_key_t *)k); return b; } } - int pcp_sanitycheck_pub(PCPCTX *ptx, pcp_pubkey_t *key) { - if(key->pub[0] == 0) { - fatal(ptx, "Pubkey sanity check: public key contained in key seems to be empty!\n"); + if (key->pub[0] == 0) { + fatal(ptx, "Pubkey sanity check: public key contained in key seems to be " + "empty!\n"); return 1; } - if(key->type != PCP_KEY_TYPE_PUBLIC) { - fatal(ptx, "Pubkey sanity check: key type is not PUBLIC (expected: %02x, got: %02x)!\n", + if (key->type != PCP_KEY_TYPE_PUBLIC) { + fatal(ptx, + "Pubkey sanity check: key type is not PUBLIC (expected: %02x, got: " + "%02x)!\n", PCP_KEY_TYPE_PUBLIC, key->type); return 1; } - if(key->version != PCP_KEY_VERSION) { - fatal(ptx, "Pubkey sanity check: unknown key version (expected: %08X, got: %08X)!\n", + if (key->version != PCP_KEY_VERSION) { + fatal(ptx, + "Pubkey sanity check: unknown key version (expected: %08X, got: " + "%08X)!\n", PCP_KEY_VERSION, key->version); return 1; } - - if(key->serial <= 0) { - fatal(ptx, "Pubkey sanity check: invalid serial number: %08X!\n", key->serial); + + if (key->serial <= 0) { + fatal(ptx, "Pubkey sanity check: invalid serial number: %08X!\n", + key->serial); return 1; } - if(key->id[16] != '\0') { + if (key->id[16] != '\0') { char *got = ucmalloc(17); memcpy(got, key->id, 17); got[16] = '\0'; - fatal(ptx, "Pubkey sanity check: invalid key id (expected 16 bytes, got: %s)!\n", got); + fatal(ptx, + "Pubkey sanity check: invalid key id (expected 16 bytes, got: %s)!\n", + got); free(got); return 1; } @@ -375,50 +379,63 @@ int pcp_sanitycheck_pub(PCPCTX *ptx, pcp_pubkey_t *key) { struct tm *c; time_t t = (time_t)key->ctime; c = localtime(&t); - if(c->tm_year <= 0 || c->tm_year > 1100) { + if (c->tm_year <= 0 || c->tm_year > 1100) { /* well, I'm perhaps overacting here :) */ - fatal(ptx, "Pubkey sanity check: invalid creation timestamp (got year %04d)!\n", c->tm_year + 1900); + fatal(ptx, + "Pubkey sanity check: invalid creation timestamp (got year %04d)!\n", + c->tm_year + 1900); return 1; } pcp_pubkey_t *maybe = pcphash_pubkeyexists(ptx, key->id); - if(maybe != NULL) { - fatal(ptx, "Pubkey sanity check: there already exists a key with the id 0x%s\n", key->id); + if (maybe != NULL) { + fatal(ptx, + "Pubkey sanity check: there already exists a key with the id 0x%s\n", + key->id); return 1; } return 0; } - int pcp_sanitycheck_key(PCPCTX *ptx, pcp_key_t *key) { - if(key->encrypted[0] == 0) { - fatal(ptx, "Secretkey sanity check: secret key contained in key seems to be empty!\n"); + if (key->encrypted[0] == 0) { + fatal(ptx, "Secretkey sanity check: secret key contained in key seems to " + "be empty!\n"); return 1; } - if(key->type != PCP_KEY_TYPE_SECRET && key->type != PCP_KEY_TYPE_MAINSECRET) { - fatal(ptx, "Secretkey sanity check: key type is not SECRET (expected: %02x, got: %02x)!\n", + if (key->type != PCP_KEY_TYPE_SECRET && + key->type != PCP_KEY_TYPE_MAINSECRET) { + fatal(ptx, + "Secretkey sanity check: key type is not SECRET (expected: %02x, " + "got: %02x)!\n", PCP_KEY_TYPE_SECRET, key->type); return 1; } - if(key->version != PCP_KEY_VERSION) { - fatal(ptx, "Secretkey sanity check: unknown key version (expected: %08X, got: %08X)!\n", + if (key->version != PCP_KEY_VERSION) { + fatal(ptx, + "Secretkey sanity check: unknown key version (expected: %08X, got: " + "%08X)!\n", PCP_KEY_VERSION, key->version); return 1; } - - if(key->serial <= 0) { - fatal(ptx, "Secretkey sanity check: invalid serial number: %08X!\n", key->serial); + + if (key->serial <= 0) { + fatal(ptx, "Secretkey sanity check: invalid serial number: %08X!\n", + key->serial); return 1; } - if(key->id[16] != '\0') { + if (key->id[16] != '\0') { char *got = ucmalloc(17); memcpy(got, key->id, 17); got[16] = '\0'; - fatal(ptx, "Secretkey sanity check: invalid key id (expected 16 bytes, got: %s)!\n", got); + fatal(ptx, + "Secretkey sanity check: invalid key id (expected 16 bytes, got: " + "%s)!\n", + got); free(got); return 1; } @@ -426,15 +443,21 @@ int pcp_sanitycheck_key(PCPCTX *ptx, pcp_key_t *key) { struct tm *c; time_t t = (time_t)key->ctime; c = localtime(&t); - if(c->tm_year <= 70 || c->tm_year > 1100) { + if (c->tm_year <= 70 || c->tm_year > 1100) { /* well, I'm perhaps overacting here :) */ - fatal(ptx, "Secretkey sanity check: invalid creation timestamp (got year %04d)!\n", c->tm_year + 1900); + fatal( + ptx, + "Secretkey sanity check: invalid creation timestamp (got year %04d)!\n", + c->tm_year + 1900); return 1; } pcp_key_t *maybe = pcphash_keyexists(ptx, key->id); - if(maybe != NULL) { - fatal(ptx, "Secretkey sanity check: there already exists a key with the id 0x%s\n", key->id); + if (maybe != NULL) { + fatal( + ptx, + "Secretkey sanity check: there already exists a key with the id 0x%s\n", + key->id); return 1; } @@ -447,35 +470,43 @@ void pcp_dumpkey(pcp_key_t *k) { printf("Dumping pcp_key_t raw values:\n"); printf("masterpub: "); - for ( i = 0;i < LEDPUB;++i) printf("%02x",(unsigned int) k->masterpub[i]); + for (i = 0; i < LEDPUB; ++i) + printf("%02x", (unsigned int)k->masterpub[i]); printf("\n"); printf(" public: "); - for ( i = 0;i < LBOXPUB;++i) printf("%02x",(unsigned int) k->pub[i]); + for (i = 0; i < LBOXPUB; ++i) + printf("%02x", (unsigned int)k->pub[i]); printf("\n"); printf(" edpub: "); - for ( i = 0;i < LEDPUB;++i) printf("%02x",(unsigned int) k->edpub[i]); + for (i = 0; i < LEDPUB; ++i) + printf("%02x", (unsigned int)k->edpub[i]); printf("\n"); printf("mastersec: "); - for ( i = 0;i < LEDSEC;++i) printf("%02x",(unsigned int) k->mastersecret[i]); + for (i = 0; i < LEDSEC; ++i) + printf("%02x", (unsigned int)k->mastersecret[i]); printf("\n"); printf(" secret: "); - for ( i = 0;i < LBOXPUB;++i) printf("%02x",(unsigned int) k->secret[i]); + for (i = 0; i < LBOXPUB; ++i) + printf("%02x", (unsigned int)k->secret[i]); printf("\n"); printf(" edsecret: "); - for ( i = 0;i < LEDSEC;++i) printf("%02x",(unsigned int) k->edsecret[i]); + for (i = 0; i < LEDSEC; ++i) + printf("%02x", (unsigned int)k->edsecret[i]); printf("\n"); printf(" nonce: "); - for ( i = 0;i < LNONCE;++i) printf("%02x",(unsigned int) k->nonce[i]); + for (i = 0; i < LNONCE; ++i) + printf("%02x", (unsigned int)k->nonce[i]); printf("\n"); printf("encrypted: "); - for ( i = 0;i < LSEC;++i) printf("%02x",(unsigned int) k->encrypted[i]); + for (i = 0; i < LSEC; ++i) + printf("%02x", (unsigned int)k->encrypted[i]); printf("\n"); printf(" owner: %s\n", k->owner); @@ -493,21 +524,23 @@ void pcp_dumpkey(pcp_key_t *k) { printf(" type: 0x%02X\n", k->type); } - void pcp_dumppubkey(pcp_pubkey_t *k) { unsigned int i; printf("Dumping pcp_pubkey_t raw values:\n"); printf("masterpub: "); - for ( i = 0;i < LEDPUB;++i) printf("%02x",(unsigned int) k->masterpub[i]); + for (i = 0; i < LEDPUB; ++i) + printf("%02x", (unsigned int)k->masterpub[i]); printf("\n"); printf(" public: "); - for ( i = 0;i < LBOXPUB;++i) printf("%02x",(unsigned int) k->pub[i]); + for (i = 0; i < LBOXPUB; ++i) + printf("%02x", (unsigned int)k->pub[i]); printf("\n"); printf(" edpub: "); - for ( i = 0;i < LEDPUB;++i) printf("%02x",(unsigned int) k->edpub[i]); + for (i = 0; i < LEDPUB; ++i) + printf("%02x", (unsigned int)k->edpub[i]); printf("\n"); printf(" owner: %s\n", k->owner); @@ -525,9 +558,8 @@ void pcp_dumppubkey(pcp_pubkey_t *k) { printf(" type: 0x%02X\n", k->type); } - /* - via + via http://rosettacode.org/wiki/Entropy#C */ double pcp_getentropy(char *source) { @@ -535,27 +567,27 @@ double pcp_getentropy(char *source) { int *hist; double H; int wherechar[256]; - int i,histlen; - + int i, histlen; + histlen = 0; H = 0; len = (int)strlen(source); - hist = (int*)calloc(len, sizeof(int)); + hist = (int *)calloc(len, sizeof(int)); - for(i=0; i<256; i++) + for (i = 0; i < 256; i++) wherechar[i] = -1; - - for(i=0; i. */ -/* #define _XOPEN_SOURCE strptime, linux glibc*/ +/* #define _XOPEN_SOURCE strptime, linux glibc*/ #include "mgmt.h" int _get_pk(Buffer *blob, pcp_pubkey_t *p) { - if(buffer_left(blob) >= 96) { + if (buffer_left(blob) >= 96) { buffer_get_chunk(blob, p->masterpub, LEDPUB); buffer_get_chunk(blob, p->edpub, LEDPUB); buffer_get_chunk(blob, p->pub, LBOXPUB); return 0; - } - else + } else return 1; } int _check_keysig_h(PCPCTX *ptx, Buffer *blob, rfc_pub_sig_h *h) { - if(buffer_left(blob) >= sizeof(rfc_pub_sig_h)) { - buffer_get_chunk(blob, h, sizeof(rfc_pub_sig_h)); /* FIXME: blog 2 struct? thafck */ + if (buffer_left(blob) >= sizeof(rfc_pub_sig_h)) { + buffer_get_chunk(blob, h, + sizeof(rfc_pub_sig_h)); /* FIXME: blog 2 struct? thafck */ h->numsubs = _wireto16((byte *)&h->numsubs); - if(h->version != EXP_SIG_VERSION) { + if (h->version != EXP_SIG_VERSION) { fatal(ptx, "Unsupported pubkey signature version %d, expected %d\n", h->version, EXP_SIG_VERSION); return 1; } - if(h->type != EXP_SIG_TYPE) { - fatal(ptx, "Unsupported pubkey signature type %d, expected %d\n", - h->type, EXP_SIG_TYPE); + if (h->type != EXP_SIG_TYPE) { + fatal(ptx, "Unsupported pubkey signature type %d, expected %d\n", h->type, + EXP_SIG_TYPE); return 1; } - if(h->pkcipher != EXP_SIG_CIPHER) { + if (h->pkcipher != EXP_SIG_CIPHER) { fatal(ptx, "Unsupported pubkey signature cipher %d, expected %d\n", h->pkcipher, EXP_SIG_CIPHER); return 1; } - if(h->hashcipher != EXP_HASH_CIPHER) { - fatal(ptx, "Unsupported pubkey signature hash cipher %d, expected %d\n", h->hashcipher, EXP_HASH_CIPHER); + if (h->hashcipher != EXP_HASH_CIPHER) { + fatal(ptx, "Unsupported pubkey signature hash cipher %d, expected %d\n", + h->hashcipher, EXP_HASH_CIPHER); return 1; } - if(h->numsubs > 0 && buffer_left(blob) < sizeof(rfc_pub_sig_s) * h->numsubs) { - fatal(ptx, "Signature size specification invalid (sig: %ld, bytes left: %ld, numsubs: %ld\n", + if (h->numsubs > 0 && + buffer_left(blob) < sizeof(rfc_pub_sig_s) * h->numsubs) { + fatal(ptx, + "Signature size specification invalid (sig: %ld, bytes left: %ld, " + "numsubs: %ld\n", sizeof(rfc_pub_sig_s) * h->numsubs, buffer_left(blob), h->numsubs); return 1; } return 0; - } - else { + } else { fatal(ptx, "Error: input data too small, import failed\n"); return 1; } } -int _check_sigsubs(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, rfc_pub_sig_s *subheader) { +int _check_sigsubs(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, + rfc_pub_sig_s *subheader) { uint16_t nsize, vsize; char *notation = NULL; - - if(subheader->size > buffer_left(blob)) { - fatal(ptx, "Invalid header size %ld specified in source\n", subheader->size); + + if (subheader->size > buffer_left(blob)) { + fatal(ptx, "Invalid header size %ld specified in source\n", + subheader->size); return 1; } - if(subheader->type == EXP_SIG_SUB_NOTATION) { + if (subheader->type == EXP_SIG_SUB_NOTATION) { /* mail or owner */ nsize = buffer_get16na(blob); vsize = buffer_get16na(blob); - if(nsize > buffer_left(blob)) { + if (nsize > buffer_left(blob)) { fatal(ptx, "Invalid notation size %ld specified in source\n", nsize); return 1; } - notation = ucmalloc(nsize+1); + notation = ucmalloc(nsize + 1); - if(buffer_get_chunk(blob, notation, nsize) == 0) { - fatal(ptx, "Invalid notation size, expected %ld bytes, but got 0\n", nsize); + if (buffer_get_chunk(blob, notation, nsize) == 0) { + fatal(ptx, "Invalid notation size, expected %ld bytes, but got 0\n", + nsize); goto sgcerr; } notation[nsize] = '\0'; - if(vsize > buffer_left(blob) || vsize > 255) { - fatal(ptx, "Invalid notation value size %ld specified in source\n", vsize); + if (vsize > buffer_left(blob) || vsize > 255) { + fatal(ptx, "Invalid notation value size %ld specified in source\n", + vsize); goto sgcerr; } - if(strncmp(notation, "owner", 5) == 0) { - if(buffer_get_chunk(blob, p->owner, vsize) == 0) { - fatal(ptx, "Invalid 'owner' notation, expected %ld bytes, but got 0\n", vsize); + if (strncmp(notation, "owner", 5) == 0) { + if (buffer_get_chunk(blob, p->owner, vsize) == 0) { + fatal(ptx, "Invalid 'owner' notation, expected %ld bytes, but got 0\n", + vsize); goto sgcerr; } - } - else if(strncmp(notation, "mail", 4) == 0) { - if(buffer_get_chunk(blob, p->mail, vsize) == 0) { - fatal(ptx, "Invalid 'mail' notation, expected %ld bytes, but got 0\n", vsize); + } else if (strncmp(notation, "mail", 4) == 0) { + if (buffer_get_chunk(blob, p->mail, vsize) == 0) { + fatal(ptx, "Invalid 'mail' notation, expected %ld bytes, but got 0\n", + vsize); goto sgcerr; } - } - else if(strncmp(notation, "serial", 6) == 0) { + } else if (strncmp(notation, "serial", 6) == 0) { p->serial = buffer_get32na(blob); } - ucfree(notation, nsize+1); - } - else { + ucfree(notation, nsize + 1); + } else { /* unsupported or ignored sig subs: we (currently) ignore sig ctime, expire and keyexpire, since the ctime - which is the only one we need internally - is already known from the key ctime. This may change in the future though. */ - if(buffer_fwd_offset(blob, subheader->size) == 0) { - fatal(ptx, "Invalid 'unsupported' notation, expected %ld bytes, but got 0\n", subheader->size); + if (buffer_fwd_offset(blob, subheader->size) == 0) { + fatal(ptx, + "Invalid 'unsupported' notation, expected %ld bytes, but got 0\n", + subheader->size); return 1; } } return 0; - sgcerr: - ucfree(notation, nsize+1); +sgcerr: + ucfree(notation, nsize + 1); return 1; } - -int _check_hash_keysig(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t *sk) { +int _check_hash_keysig(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, + pcp_keysig_t *sk) { // read hash + sig size_t blobstop = blob->offset; /* key header + mp,sp,cp */ size_t sigsize = crypto_sign_BYTES + crypto_generichash_BYTES_MAX; size_t phead = (2 * sizeof(uint8_t)) + sizeof(uint64_t); /* rfc_pub_h */ byte *signature = ucmalloc(sigsize); - if(buffer_get_chunk(blob, signature, sigsize) == 0) + if (buffer_get_chunk(blob, signature, sigsize) == 0) goto chker1; /* fill the keysig */ sk->type = PCP_KEYSIG_NATIVE; - + /* everything minus version, ctime and cipher, 1st 3 fields */ sk->size = blobstop - phead; @@ -169,7 +177,7 @@ int _check_hash_keysig(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t /* verify the signature */ byte *verifyhash = pcp_ed_verify_key(ptx, signature, sigsize, p); - if(verifyhash == NULL) { + if (verifyhash == NULL) { goto chker1; } @@ -181,21 +189,22 @@ int _check_hash_keysig(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t crypto_generichash_final(st, hash, crypto_generichash_BYTES_MAX); /* compare them */ - if(cst_time_memcmp(hash, verifyhash, crypto_generichash_BYTES_MAX) != 0) { - fatal(ptx, "Signature verifies but signed hash doesn't match signature contents\n"); + if (cst_time_memcmp(hash, verifyhash, crypto_generichash_BYTES_MAX) != 0) { + fatal(ptx, "Signature verifies but signed hash doesn't match signature " + "contents\n"); goto chker2; } /* calculate the checksum */ crypto_hash_sha256(sk->checksum, sk->blob, sk->size); - + /* we got here, so everything is good */ p->valid = 1; /* append the sig */ memcpy(&sk->blob[sk->size], signature, sigsize); sk->size += sigsize; - + ucfree(verifyhash, crypto_generichash_BYTES_MAX); ucfree(hash, crypto_generichash_BYTES_MAX); free(st); @@ -203,25 +212,23 @@ int _check_hash_keysig(PCPCTX *ptx, Buffer *blob, pcp_pubkey_t *p, pcp_keysig_t return 0; - chker2: +chker2: ucfree(verifyhash, crypto_generichash_BYTES_MAX); ucfree(hash, crypto_generichash_BYTES_MAX); free(st); - chker1: +chker1: ucfree(signature, sigsize); return 1; - } - pcp_ks_bundle_t *pcp_import_pub(PCPCTX *ptx, byte *raw, size_t rawsize) { size_t clen; byte *bin = NULL; char *z85 = NULL; - if(rawsize == 0) { + if (rawsize == 0) { fatal(ptx, "Input file is empty!\n"); return NULL; } @@ -231,15 +238,14 @@ pcp_ks_bundle_t *pcp_import_pub(PCPCTX *ptx, byte *raw, size_t rawsize) { /* first, try to decode the input */ z85 = pcp_readz85string(ptx, raw, rawsize); - if(z85 != NULL) + if (z85 != NULL) bin = pcp_z85_decode(ptx, z85, &clen); - if(bin == NULL) { + if (bin == NULL) { /* treat as binary blob */ fatals_reset(ptx); buffer_add(blob, raw, rawsize); - } - else { + } else { /* use decoded */ buffer_add(blob, bin, clen); ucfree(bin, clen); @@ -248,11 +254,10 @@ pcp_ks_bundle_t *pcp_import_pub(PCPCTX *ptx, byte *raw, size_t rawsize) { /* now, try to disassemble, if it fails, assume pbp format */ uint8_t version = buffer_get8(blob); - if(version == PCP_KEY_VERSION) { + if (version == PCP_KEY_VERSION) { /* ah, homerun */ return pcp_import_pub_rfc(ptx, blob); - } - else { + } else { /* nope, it's probably pbp */ return pcp_import_pub_pbp(ptx, blob); } @@ -263,22 +268,20 @@ pcp_ks_bundle_t *pcp_import_binpub(PCPCTX *ptx, byte *raw, size_t rawsize) { pcp_ks_bundle_t *bundle = NULL; #ifdef HAVE_JSON - if(ptx->json) { + if (ptx->json) { bundle = pcp_import_pub_json(ptx, raw, rawsize); - } - else { + } else { #endif - + buffer_add(blob, raw, rawsize); /* now, try to disassemble, if it fails, assume pbp format */ uint8_t version = buffer_get8(blob); - if(version == PCP_KEY_VERSION) { + if (version == PCP_KEY_VERSION) { /* ah, homerun */ bundle = pcp_import_pub_rfc(ptx, blob); - } - else { + } else { /* nope, it's probably pbp */ bundle = pcp_import_pub_pbp(ptx, blob); } @@ -286,10 +289,9 @@ pcp_ks_bundle_t *pcp_import_binpub(PCPCTX *ptx, byte *raw, size_t rawsize) { #ifdef HAVE_JSON } #endif - + buffer_free(blob); return bundle; - } pcp_ks_bundle_t *pcp_import_pub_rfc(PCPCTX *ptx, Buffer *blob) { @@ -299,31 +301,34 @@ pcp_ks_bundle_t *pcp_import_pub_rfc(PCPCTX *ptx, Buffer *blob) { rfc_pub_sig_s *subheader = ucmalloc(sizeof(rfc_pub_sig_s)); pcp_pubkey_t *p = ucmalloc(sizeof(pcp_pubkey_t)); - if(buffer_done(blob)) goto be; + if (buffer_done(blob)) + goto be; p->ctime = buffer_get64na(blob); uint8_t pkcipher = buffer_get8(blob); - if(buffer_done(blob)) goto be; + if (buffer_done(blob)) + goto be; - if(pkcipher != EXP_PK_CIPHER) { - fatal(ptx, "Unsupported pk cipher %d, expected %d\n", pkcipher, EXP_PK_CIPHER); + if (pkcipher != EXP_PK_CIPHER) { + fatal(ptx, "Unsupported pk cipher %d, expected %d\n", pkcipher, + EXP_PK_CIPHER); goto bef; } /* fetch pk material */ - if(_get_pk(blob, p) != 0) + if (_get_pk(blob, p) != 0) goto be; /* check sig header */ - if(_check_keysig_h(ptx, blob, sigheader) != 0) + if (_check_keysig_h(ptx, blob, sigheader) != 0) goto bef; /* iterate over subs, if any */ int i; - for (i=0; inumsubs; i++) { + for (i = 0; i < sigheader->numsubs; i++) { subheader->size = buffer_get32na(blob); subheader->type = buffer_get8(blob); - if(_check_sigsubs(ptx, blob, p, subheader) != 0) + if (_check_sigsubs(ptx, blob, p, subheader) != 0) goto bes; } ucfree(sigheader, sizeof(rfc_pub_sig_h)); @@ -342,24 +347,22 @@ pcp_ks_bundle_t *pcp_import_pub_rfc(PCPCTX *ptx, Buffer *blob) { b = ucmalloc(sizeof(pcp_ks_bundle_t)); sk = ucmalloc(sizeof(pcp_keysig_t)); - if(_check_hash_keysig(ptx, blob, p, sk) != 0) { + if (_check_hash_keysig(ptx, blob, p, sk) != 0) { b->p = p; b->s = NULL; - } - else { + } else { b->p = p; b->s = sk; } return b; - - be: +be: fatal(ptx, "Error: input data too small, import failed\n"); - bes: +bes: - bef: +bef: ucfree(sigheader, sizeof(rfc_pub_sig_h)); ucfree(subheader, sizeof(rfc_pub_sig_s)); ucfree(p, sizeof(pcp_pubkey_t)); @@ -367,7 +370,7 @@ pcp_ks_bundle_t *pcp_import_pub_rfc(PCPCTX *ptx, Buffer *blob) { } pcp_ks_bundle_t *pcp_import_pub_pbp(PCPCTX *ptx, Buffer *blob) { - char *date = ucmalloc(20); + char *date = ucmalloc(20); char *parts = NULL; byte *sig = ucmalloc(crypto_sign_BYTES); int pnum; @@ -378,7 +381,7 @@ pcp_ks_bundle_t *pcp_import_pub_pbp(PCPCTX *ptx, Buffer *blob) { buffer_get_chunk(blob, sig, crypto_sign_BYTES); /* make sure it's a pbp */ - if(_buffer_is_binary(sig, crypto_sign_BYTES) == 0) { + if (_buffer_is_binary(sig, crypto_sign_BYTES) == 0) { fatal(ptx, "failed to recognize input, that's probably no key\n"); goto errimp2; } @@ -392,10 +395,10 @@ pcp_ks_bundle_t *pcp_import_pub_pbp(PCPCTX *ptx, Buffer *blob) { date[19] = '\0'; struct tm c; c.tm_isdst = -1; - int tmok = sscanf(date, "%4d-%2d-%2dT%2d:%2d:%2d", - &c.tm_year, &c.tm_mon, &c.tm_mday, &c.tm_hour, &c.tm_min, &c.tm_sec); - - if(tmok <= 0 || c.tm_hour >= 24 || c.tm_mon >= 59 || c.tm_sec >= 59) { + int tmok = sscanf(date, "%4d-%2d-%2dT%2d:%2d:%2d", &c.tm_year, &c.tm_mon, + &c.tm_mday, &c.tm_hour, &c.tm_min, &c.tm_sec); + + if (tmok <= 0 || c.tm_hour >= 24 || c.tm_mon >= 59 || c.tm_sec >= 59) { /* check returned tm values, which will look like this when input was no string: 30867--12305-0 4229688:8:21790784 or: sscanf failed altogether. @@ -408,13 +411,13 @@ pcp_ks_bundle_t *pcp_import_pub_pbp(PCPCTX *ptx, Buffer *blob) { c.tm_mon -= 1; c.tm_year -= 1900; - + /* parse the name */ - parts = strtok (b->name, "<>"); + parts = strtok(b->name, "<>"); pnum = 0; pub = ucmalloc(sizeof(pcp_pubkey_t)); while (parts != NULL) { - if(pnum == 0) + if (pnum == 0) memcpy(pub->owner, parts, strlen(parts)); else if (pnum == 1) memcpy(pub->mail, parts, strlen(parts)); @@ -423,7 +426,7 @@ pcp_ks_bundle_t *pcp_import_pub_pbp(PCPCTX *ptx, Buffer *blob) { } free(parts); - if(strlen(b->name) == 0) { + if (strlen(b->name) == 0) { memcpy(pub->owner, "N/A", 3); } @@ -431,7 +434,7 @@ pcp_ks_bundle_t *pcp_import_pub_pbp(PCPCTX *ptx, Buffer *blob) { pub->ctime = (long)mktime(&c); pub->type = PCP_KEY_TYPE_PUBLIC; pub->version = PCP_KEY_VERSION; - pub->serial = arc4random(); + pub->serial = arc4random(); memcpy(pub->pub, b->pub, crypto_box_PUBLICKEYBYTES); memcpy(pub->edpub, b->edpub, crypto_sign_PUBLICKEYBYTES); memcpy(pub->id, pcp_getpubkeyid(pub), 17); @@ -447,12 +450,11 @@ pcp_ks_bundle_t *pcp_import_pub_pbp(PCPCTX *ptx, Buffer *blob) { pcp_ks_bundle_t *bundle = ucmalloc(sizeof(pcp_ks_bundle_t)); bundle->p = pub; - - if(verify == NULL) { + + if (verify == NULL) { bundle->p = pub; bundle->s = NULL; - } - else { + } else { pcp_keysig_t *sk = ucmalloc(sizeof(pcp_keysig_t)); sk->type = PCP_KEYSIG_PBP; sk->size = buffer_size(blob); @@ -465,16 +467,15 @@ pcp_ks_bundle_t *pcp_import_pub_pbp(PCPCTX *ptx, Buffer *blob) { bundle->p = pub; free(verify); } - + free(sig); return bundle; - errimp2: +errimp2: free(sig); return NULL; } - Buffer *pcp_export_pbp_pub(pcp_key_t *sk) { struct tm *v, *c; byte *signature = NULL; @@ -494,11 +495,12 @@ Buffer *pcp_export_pbp_pub(pcp_key_t *sk) { time_t vt = t + 31536000; v = localtime(&vt); date = ucmalloc(65); - sprintf(date, "%04d-%02d-%02dT%02d:%02d:%02d.000000 %04d-%02d-%02dT%02d:%02d:%02d.000000 ", - c->tm_year+1900-1, c->tm_mon+1, c->tm_mday, // wtf? why -1? - c->tm_hour, c->tm_min, c->tm_sec, - v->tm_year+1900-1, v->tm_mon+1, v->tm_mday, - v->tm_hour, v->tm_min, v->tm_sec); + sprintf(date, + "%04d-%02d-%02dT%02d:%02d:%02d.000000 " + "%04d-%02d-%02dT%02d:%02d:%02d.000000 ", + c->tm_year + 1900 - 1, c->tm_mon + 1, c->tm_mday, // wtf? why -1? + c->tm_hour, c->tm_min, c->tm_sec, v->tm_year + 1900 - 1, + v->tm_mon + 1, v->tm_mday, v->tm_hour, v->tm_min, v->tm_sec); buffer_add(sig, date, 64); /* add owner */ @@ -507,7 +509,7 @@ Buffer *pcp_export_pbp_pub(pcp_key_t *sk) { /* calculate the signed key blob */ signature = pcp_ed_sign(buffer_get(sig), buffer_size(sig), sk); - if(signature == NULL) + if (signature == NULL) goto exppbperr01; /* put it out */ @@ -516,9 +518,8 @@ Buffer *pcp_export_pbp_pub(pcp_key_t *sk) { free(date); buffer_free(sig); return out; - - exppbperr01: +exppbperr01: buffer_free(sig); buffer_free(out); free(date); @@ -526,11 +527,10 @@ Buffer *pcp_export_pbp_pub(pcp_key_t *sk) { return NULL; } - -Buffer *pcp_export_rfc_pub (PCPCTX *ptx, pcp_key_t *sk) { +Buffer *pcp_export_rfc_pub(PCPCTX *ptx, pcp_key_t *sk) { Buffer *out = buffer_new(320, "exportbuf"); Buffer *raw = buffer_new(256, "keysigbuf"); - + /* add the header */ buffer_add8(out, PCP_KEY_VERSION); buffer_add64be(out, sk->ctime); @@ -551,9 +551,9 @@ Buffer *pcp_export_rfc_pub (PCPCTX *ptx, pcp_key_t *sk) { ctime, sigexpire, keyexpire, serial, keyflags optional: owner, mail */ uint16_t nsubs = 5; - if(strlen(sk->owner) > 0) + if (strlen(sk->owner) > 0) nsubs++; - if(strlen(sk->mail) > 0) + if (strlen(sk->mail) > 0) nsubs++; buffer_add16be(raw, nsubs); @@ -583,7 +583,7 @@ Buffer *pcp_export_rfc_pub (PCPCTX *ptx, pcp_key_t *sk) { buffer_add32be(raw, sk->serial); /* add name notation sub*/ - if(strlen(sk->owner) > 0) { + if (strlen(sk->owner) > 0) { size_t notation_size = strlen(sk->owner) + 4 + 5; buffer_add32be(raw, notation_size); buffer_add8(raw, EXP_SIG_SUB_NOTATION); @@ -594,7 +594,7 @@ Buffer *pcp_export_rfc_pub (PCPCTX *ptx, pcp_key_t *sk) { } /* add mail notation sub */ - if(strlen(sk->mail) > 0) { + if (strlen(sk->mail) > 0) { notation_size = strlen(sk->mail) + 4 + 4; buffer_add32be(raw, notation_size); buffer_add8(raw, EXP_SIG_SUB_NOTATION); @@ -603,7 +603,7 @@ Buffer *pcp_export_rfc_pub (PCPCTX *ptx, pcp_key_t *sk) { buffer_add(raw, "mail", 4); buffer_add(raw, sk->mail, strlen(sk->mail)); } - + /* add key flags */ buffer_add32be(raw, 1); buffer_add8(raw, EXP_SIG_SUB_KEYFLAGS); @@ -627,8 +627,8 @@ Buffer *pcp_export_rfc_pub (PCPCTX *ptx, pcp_key_t *sk) { buffer_add(out, sig, crypto_sign_BYTES + crypto_generichash_BYTES_MAX); #ifdef HAVE_JSON - if(ptx->json) { - size_t siglen = buffer_size(out) - 10; + if (ptx->json) { + size_t siglen = buffer_size(out) - 10; byte *jsig = ucmalloc(siglen); buffer_extract(out, jsig, 10, siglen); @@ -639,7 +639,7 @@ Buffer *pcp_export_rfc_pub (PCPCTX *ptx, pcp_key_t *sk) { out = jout; } #endif - + /* and that's it. wasn't that easy? :) */ buffer_free(raw); memset(hash, 0, crypto_generichash_BYTES_MAX); @@ -648,7 +648,7 @@ Buffer *pcp_export_rfc_pub (PCPCTX *ptx, pcp_key_t *sk) { free(sig); free(st); - if(out->end < 32) + if (out->end < 32) fatal(ptx, "failed to export public key"); return out; @@ -671,37 +671,35 @@ Buffer *pcp_export_secret(PCPCTX *ptx, pcp_key_t *sk, char *passphrase) { buffer_add(raw, sk->pub, LBOXPUB); buffer_add(raw, sk->edpub, LEDPUB); - if(strlen(sk->owner) > 0) { + if (strlen(sk->owner) > 0) { buffer_add16be(raw, strlen(sk->owner)); - buffer_add(raw, sk->owner, strlen(sk->owner)); - } - else + buffer_add(raw, sk->owner, strlen(sk->owner)); + } else buffer_add16be(raw, 0); - - if(strlen(sk->mail) > 0) { + + if (strlen(sk->mail) > 0) { buffer_add16be(raw, strlen(sk->mail)); buffer_add(raw, sk->mail, strlen(sk->mail)); - } - else + } else buffer_add16be(raw, 0); - + buffer_add64be(raw, sk->ctime); buffer_add32be(raw, sk->version); buffer_add32be(raw, sk->serial); - + nonce = ucmalloc(LNONCE); arc4random_buf(nonce, LNONCE); symkey = pcp_scrypt(ptx, passphrase, strlen(passphrase), nonce, LNONCE); - es = pcp_sodium_mac(&cipher, buffer_get(raw), buffer_size(raw), nonce, symkey); + es = + pcp_sodium_mac(&cipher, buffer_get(raw), buffer_size(raw), nonce, symkey); #ifdef HAVE_JSON - if(ptx->json) { + if (ptx->json) { Buffer *jout = pcp_export_json_secret(ptx, sk, nonce, cipher, es); buffer_free(out); out = jout; - } - else { + } else { #endif buffer_add(out, nonce, LNONCE); @@ -709,8 +707,8 @@ Buffer *pcp_export_secret(PCPCTX *ptx, pcp_key_t *sk, char *passphrase) { #ifdef HAVE_JSON } -#endif - +#endif + buffer_free(raw); ucfree(nonce, LNONCE); sfree(symkey); @@ -719,19 +717,20 @@ Buffer *pcp_export_secret(PCPCTX *ptx, pcp_key_t *sk, char *passphrase) { return out; } -pcp_key_t *pcp_import_binsecret(PCPCTX *ptx, byte *raw, size_t rawsize, char *passphrase) { +pcp_key_t *pcp_import_binsecret(PCPCTX *ptx, byte *raw, size_t rawsize, + char *passphrase) { Buffer *blob = buffer_new(512, "importskblob"); buffer_add(blob, raw, rawsize); return pcp_import_secret_native(ptx, blob, passphrase); } - -pcp_key_t *pcp_import_secret(PCPCTX *ptx, byte *raw, size_t rawsize, char *passphrase) { +pcp_key_t *pcp_import_secret(PCPCTX *ptx, byte *raw, size_t rawsize, + char *passphrase) { size_t clen; byte *bin = NULL; char *z85 = NULL; - if(rawsize == 0) { + if (rawsize == 0) { fatal(ptx, "Input file is empty!\n"); return NULL; } @@ -740,15 +739,14 @@ pcp_key_t *pcp_import_secret(PCPCTX *ptx, byte *raw, size_t rawsize, char *passp /* first, try to decode the input */ z85 = pcp_readz85string(ptx, raw, rawsize); - if(z85 != NULL) + if (z85 != NULL) bin = pcp_z85_decode(ptx, z85, &clen); - if(bin == NULL) { + if (bin == NULL) { /* treat as binary blob */ fatals_reset(ptx); buffer_add(blob, raw, rawsize); - } - else { + } else { /* use decoded */ buffer_add(blob, bin, clen); ucfree(bin, clen); @@ -761,44 +759,48 @@ pcp_key_t *pcp_import_secret(PCPCTX *ptx, byte *raw, size_t rawsize, char *passp return sk; } -pcp_key_t *pcp_import_secret_native(PCPCTX *ptx, Buffer *cipher, char *passphrase) { +pcp_key_t *pcp_import_secret_native(PCPCTX *ptx, Buffer *cipher, + char *passphrase) { pcp_key_t *sk = ucmalloc(sizeof(pcp_key_t)); byte *nonce = ucmalloc(LNONCE); byte *symkey = NULL; byte *clear = NULL; size_t cipherlen = 0; - size_t minlen = (LEDSEC * 2) + (LBOXPUB * 2) + (LEDPUB * 2) + 8 + 4 + 4; /* key material and mandatory field sizes */ + size_t minlen = (LEDSEC * 2) + (LBOXPUB * 2) + (LEDPUB * 2) + 8 + 4 + + 4; /* key material and mandatory field sizes */ uint16_t notationlen = 0; Buffer *blob = buffer_new(512, "secretdecryptbuf"); - + #ifdef HAVE_JSON - if(ptx->json) { + if (ptx->json) { Buffer *parsed = pcp_import_secret_json(ptx, cipher); - if(parsed == NULL) { + if (parsed == NULL) { goto impserr1; } cipher = parsed; /* re-used */ } #endif - if(buffer_get_chunk(cipher, nonce, LNONCE) == 0) + if (buffer_get_chunk(cipher, nonce, LNONCE) == 0) goto impserr1; symkey = pcp_scrypt(ptx, passphrase, strlen(passphrase), nonce, LNONCE); cipherlen = buffer_left(cipher); - if(cipherlen < minlen) { - fatal(ptx, "failed to decrypt the secret key file:\n" - "expected encrypted secret key size %ld is less than minimum len %ld\n", - cipherlen, minlen); + if (cipherlen < minlen) { + fatal( + ptx, + "failed to decrypt the secret key file:\n" + "expected encrypted secret key size %ld is less than minimum len %ld\n", + cipherlen, minlen); goto impserr1; } /* decrypt the blob */ clear = ucmalloc(cipherlen - LMAC); - if(pcp_sodium_verify_mac(&clear, buffer_get_remainder(cipher), - cipherlen, nonce, symkey) != 0) { + if (pcp_sodium_verify_mac(&clear, buffer_get_remainder(cipher), cipherlen, + nonce, symkey) != 0) { fatal(ptx, "failed to decrypt the secret key file\n"); goto impserr2; @@ -817,34 +819,33 @@ pcp_key_t *pcp_import_secret_native(PCPCTX *ptx, Buffer *cipher, char *passphras buffer_get_chunk(blob, sk->edpub, LEDPUB); notationlen = buffer_get16na(blob); - if(notationlen > 255) { - fatal(ptx, "Invalid notation value size for owner (got: %ld, expected: 255)\n", + if (notationlen > 255) { + fatal(ptx, + "Invalid notation value size for owner (got: %ld, expected: 255)\n", notationlen); goto impserr2; - } - else if(notationlen > 0) + } else if (notationlen > 0) buffer_get_chunk(blob, sk->owner, notationlen); notationlen = buffer_get16na(blob); - if(notationlen > 255) { - fatal(ptx, "Invalid notation value size for mail (got: %ld, expected: 255)\n", + if (notationlen > 255) { + fatal(ptx, + "Invalid notation value size for mail (got: %ld, expected: 255)\n", notationlen); goto impserr2; - } - else if(notationlen > 0) + } else if (notationlen > 0) buffer_get_chunk(blob, sk->mail, notationlen); - if(buffer_done(blob) == 1) + if (buffer_done(blob) == 1) goto impserr2; sk->ctime = buffer_get64na(blob); sk->version = buffer_get32na(blob); sk->serial = buffer_get32na(blob); - /* fill in the calculated fields */ char *id = pcp_getkeyid(sk); - memcpy (sk->id, id, 17); + memcpy(sk->id, id, 17); sk->type = PCP_KEY_TYPE_SECRET; /* ready */ @@ -856,25 +857,18 @@ pcp_key_t *pcp_import_secret_native(PCPCTX *ptx, Buffer *cipher, char *passphras return sk; - impserr2: +impserr2: ucfree(clear, cipherlen - LMAC); - impserr1: +impserr1: ucfree(nonce, LNONCE); ucfree(sk, sizeof(pcp_key_t)); buffer_free(blob); - if(symkey != NULL) + if (symkey != NULL) sfree(symkey); return NULL; } - - - - - - - #ifdef HAVE_JSON json_t *pcp_pk2json(pcp_pubkey_t *pk) { @@ -883,7 +877,7 @@ json_t *pcp_pk2json(pcp_pubkey_t *pk) { for both key types. FIXME: 'd be better to have just 1 struct for both types... */ json_t *out; - + pcp_key_t *sk = malloc(sizeof(pcp_key_t)); memcpy(sk->masterpub, pk->masterpub, LEDPUB); @@ -906,99 +900,89 @@ json_t *pcp_pk2json(pcp_pubkey_t *pk) { json_t *pcp_sk2json(pcp_key_t *sk, byte *sig, size_t siglen) { json_t *jout; char *cryptpub, *sigpub, *masterpub, *ssig; - + char *jformat = "{sssssssIsIsIsIssssssssssss}"; cryptpub = _bin2hex(sk->pub, LBOXPUB); - sigpub = _bin2hex(sk->edpub, LEDPUB); - masterpub= _bin2hex(sk->masterpub, LEDPUB); - - if(sig != NULL) { - ssig = _bin2hex(sig, siglen); - } - else { + sigpub = _bin2hex(sk->edpub, LEDPUB); + masterpub = _bin2hex(sk->masterpub, LEDPUB); + + if (sig != NULL) { + ssig = _bin2hex(sig, siglen); + } else { ssig = malloc(1); ssig[0] = '\0'; jformat = "{sssssssIsIsIsIssssssssss}"; } - jout = json_pack(jformat, - "id" , sk->id, - "owner" , sk->owner, - "mail" , sk->mail, - "ctime" , (json_int_t)sk->ctime, - "expire" , (json_int_t)sk->ctime+31536000, - "version" , (json_int_t)sk->version, - "serial" , (json_int_t)sk->serial, - "type" , "public", - "cipher" , EXP_PK_CIPHER_NAME, - "cryptpub" , cryptpub, - "sigpub" , sigpub, - "masterpub" , masterpub, - "signature" , ssig - ); + jout = json_pack( + jformat, "id", sk->id, "owner", sk->owner, "mail", sk->mail, "ctime", + (json_int_t)sk->ctime, "expire", (json_int_t)sk->ctime + 31536000, + "version", (json_int_t)sk->version, "serial", (json_int_t)sk->serial, + "type", "public", "cipher", EXP_PK_CIPHER_NAME, "cryptpub", cryptpub, + "sigpub", sigpub, "masterpub", masterpub, "signature", ssig); free(cryptpub); free(sigpub); free(masterpub); - if(sig != NULL) + if (sig != NULL) free(ssig); return jout; } -Buffer *pcp_export_json_secret(PCPCTX *ptx, pcp_key_t *sk, byte *nonce, byte *cipher, size_t clen) { +Buffer *pcp_export_json_secret(PCPCTX *ptx, pcp_key_t *sk, byte *nonce, + byte *cipher, size_t clen) { Buffer *b = buffer_new_str("jsonbuf"); char *jdump, *xcipher, *xnonce; json_t *jout; json_error_t jerror; - + assert(ptx->json); jout = pcp_sk2json(sk, NULL, 0); xcipher = _bin2hex(cipher, clen); - xnonce = _bin2hex(nonce, LNONCE); + xnonce = _bin2hex(nonce, LNONCE); json_object_set(jout, "type", json_string("secret")); json_object_set(jout, "secrets", json_string(xcipher)); json_object_set(jout, "nonce", json_string(xnonce)); - jdump = json_dumps(jout, JSON_INDENT(4) | JSON_PRESERVE_ORDER); - if(jdump != NULL) { + jdump = json_dumps(jout, JSON_INDENT(4) | JSON_PRESERVE_ORDER); + if (jdump != NULL) { buffer_add(b, jdump, strlen(jdump)); free(jdump); - } - else { + } else { fatal(ptx, "JSON encoding error: %s", jerror.text); } - + json_decref(jout); - + return b; } -Buffer *pcp_export_json_pub(PCPCTX *ptx, pcp_key_t *sk, byte *sig, size_t siglen) { +Buffer *pcp_export_json_pub(PCPCTX *ptx, pcp_key_t *sk, byte *sig, + size_t siglen) { Buffer *b = buffer_new_str("jsonbuf"); char *jdump; json_t *jout; json_error_t jerror; - + assert(ptx->json); jout = pcp_sk2json(sk, sig, siglen); - jdump = json_dumps(jout, JSON_INDENT(4) | JSON_PRESERVE_ORDER); + jdump = json_dumps(jout, JSON_INDENT(4) | JSON_PRESERVE_ORDER); - if(jdump != NULL) { + if (jdump != NULL) { buffer_add(b, jdump, strlen(jdump)); free(jdump); - } - else { + } else { fatal(ptx, "JSON encoding error: %s", jerror.text); } - + json_decref(jout); - + return b; } @@ -1008,9 +992,10 @@ Buffer *pcp_import_secret_json(PCPCTX *ptx, Buffer *json) { size_t maxblob = 2048; size_t binlen; char *hexerr = "failed to decode hex string"; - - jin = json_loadb((char *)buffer_get(json), buffer_size(json), JSON_DISABLE_EOF_CHECK, &jerror); - if(jin == NULL) + + jin = json_loadb((char *)buffer_get(json), buffer_size(json), + JSON_DISABLE_EOF_CHECK, &jerror); + if (jin == NULL) goto jirr1; byte *blob = ucmalloc(maxblob); @@ -1019,36 +1004,36 @@ Buffer *pcp_import_secret_json(PCPCTX *ptx, Buffer *json) { json->offset = 0; jtmp = json_object_get(jin, "nonce"); - if(jtmp == NULL) + if (jtmp == NULL) goto jirr2; binlen = _hex2bin(json_string_value(jtmp), blob, maxblob); - if(binlen > 1) + if (binlen > 1) buffer_add(json, blob, binlen); else { strcpy(jerror.text, hexerr); goto jirr2; } - + jtmp = json_object_get(jin, "secrets"); - if(jtmp == NULL) + if (jtmp == NULL) goto jirr2; binlen = _hex2bin(json_string_value(jtmp), blob, maxblob); - if(binlen > 1) + if (binlen > 1) buffer_add(json, blob, binlen); else { strcpy(jerror.text, hexerr); goto jirr2; } - + json_decref(jin); ucfree(blob, maxblob); return json; - - jirr2: + +jirr2: ucfree(blob, maxblob); json_decref(jin); - - jirr1: + +jirr1: fatal(ptx, "JSON decoding error: %s", jerror.text); return NULL; } @@ -1063,25 +1048,25 @@ pcp_ks_bundle_t *pcp_import_pub_json(PCPCTX *ptx, byte *raw, size_t rawsize) { size_t maxblob = 2048; const char *stmp; char *hexerr = "failed to decode hex string"; - + jin = json_loadb((char *)raw, rawsize, JSON_DISABLE_EOF_CHECK, &jerror); - if(jin == NULL) + if (jin == NULL) goto jerr1; - + p = ucmalloc(sizeof(pcp_pubkey_t)); - s = ucmalloc(sizeof(pcp_keysig_t)); - b = ucmalloc(sizeof(pcp_ks_bundle_t)); + s = ucmalloc(sizeof(pcp_keysig_t)); + b = ucmalloc(sizeof(pcp_ks_bundle_t)); blob = ucmalloc(maxblob); - + jtmp = json_object_get(jin, "id"); - if(jtmp == NULL) + if (jtmp == NULL) goto jerr2; memcpy(p->id, json_string_value(jtmp), 17); jtmp = json_object_get(jin, "cryptpub"); - if(jtmp == NULL) + if (jtmp == NULL) goto jerr2; - if(_hex2bin(json_string_value(jtmp), blob, maxblob) == LBOXPUB) + if (_hex2bin(json_string_value(jtmp), blob, maxblob) == LBOXPUB) memcpy(p->pub, blob, LBOXPUB); else { strcpy(jerror.text, hexerr); @@ -1089,9 +1074,9 @@ pcp_ks_bundle_t *pcp_import_pub_json(PCPCTX *ptx, byte *raw, size_t rawsize) { } jtmp = json_object_get(jin, "sigpub"); - if(jtmp == NULL) + if (jtmp == NULL) goto jerr2; - if(_hex2bin(json_string_value(jtmp), blob, maxblob) == LEDPUB) + if (_hex2bin(json_string_value(jtmp), blob, maxblob) == LEDPUB) memcpy(p->edpub, blob, LEDPUB); else { strcpy(jerror.text, hexerr); @@ -1099,9 +1084,9 @@ pcp_ks_bundle_t *pcp_import_pub_json(PCPCTX *ptx, byte *raw, size_t rawsize) { } jtmp = json_object_get(jin, "masterpub"); - if(jtmp == NULL) + if (jtmp == NULL) goto jerr2; - if(_hex2bin(json_string_value(jtmp), blob, maxblob) == LEDPUB) + if (_hex2bin(json_string_value(jtmp), blob, maxblob) == LEDPUB) memcpy(p->masterpub, blob, LEDPUB); else { strcpy(jerror.text, hexerr); @@ -1109,42 +1094,42 @@ pcp_ks_bundle_t *pcp_import_pub_json(PCPCTX *ptx, byte *raw, size_t rawsize) { } jtmp = json_object_get(jin, "owner"); - if(jtmp == NULL) + if (jtmp == NULL) goto jerr2; stmp = json_string_value(jtmp); - if(stmp != NULL) + if (stmp != NULL) strcpy(p->owner, stmp); else goto jerr2; - + jtmp = json_object_get(jin, "mail"); - if(jtmp == NULL) + if (jtmp == NULL) goto jerr2; stmp = json_string_value(jtmp); - if(stmp != NULL) + if (stmp != NULL) strcpy(p->mail, stmp); else goto jerr2; jtmp = json_object_get(jin, "ctime"); - if(jtmp == NULL) + if (jtmp == NULL) goto jerr2; p->ctime = (uint64_t)json_integer_value(jtmp); jtmp = json_object_get(jin, "version"); - if(jtmp == NULL) + if (jtmp == NULL) goto jerr2; p->version = (uint32_t)json_integer_value(jtmp); jtmp = json_object_get(jin, "serial"); - if(jtmp == NULL) + if (jtmp == NULL) goto jerr2; p->serial = (uint32_t)json_integer_value(jtmp); - + jtmp = json_object_get(jin, "type"); - if(jtmp == NULL) + if (jtmp == NULL) goto jerr2; - if(json_string_value(jtmp)[0] == 'p') + if (json_string_value(jtmp)[0] == 'p') p->type = PCP_KEY_TYPE_PUBLIC; else { strcpy(jerror.text, "key type is not public"); @@ -1162,43 +1147,42 @@ pcp_ks_bundle_t *pcp_import_pub_json(PCPCTX *ptx, byte *raw, size_t rawsize) { */ jtmp = json_object_get(jin, "signature"); - if(jtmp == NULL) + if (jtmp == NULL) goto jerr2; size_t siglen = _hex2bin(json_string_value(jtmp), blob, maxblob); - if(siglen > 1) { + if (siglen > 1) { /* we're fakin' an rfc blob here, so that _check_hash_keysig() get's what it expects and we don't have to implement it twice */ Buffer *btmp = buffer_new(128, "btmp"); - byte fake[10] = { 0x00 }; + byte fake[10] = {0x00}; buffer_add(btmp, fake, 10); buffer_add(btmp, blob, siglen); btmp->offset = buffer_size(btmp) - - (crypto_sign_BYTES + crypto_generichash_BYTES_MAX); /* 32*3 keys + 10 header */ + (crypto_sign_BYTES + + crypto_generichash_BYTES_MAX); /* 32*3 keys + 10 header */ - if(_check_hash_keysig(ptx, btmp, p, s) != 0) { + if (_check_hash_keysig(ptx, btmp, p, s) != 0) { b->s = NULL; - } - else { + } else { b->s = s; } buffer_free(btmp); - } - else { + } else { strcpy(jerror.text, "sigerr"); goto jerr2; } - return b; + return b; - jerr2: +jerr2: free(p); free(s); free(b); free(blob); json_decref(jin); - - jerr1: + +jerr1: fatal(ptx, "JSON decoding error: %s", jerror.text); return NULL; } diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..83dfe2f --- /dev/null +++ b/meson.build @@ -0,0 +1,120 @@ +# -*-python-*- + +project( + 'pcp', + 'c', + license: 'GPL', + version: '0.4.1', + meson_version: '>=1.3', + default_options: [ + 'warning_level=2', + 'werror=true', + ], +) + +add_project_arguments( + [ + '-Wno-unused-parameter', + '-Wno-unused-result', + '-Wno-missing-braces', + '-Wno-format-zero-length', + '-Wno-implicit-fallthrough', + #'-Wvla', + '-Wno-sign-compare', + '-Wno-narrowing' + ], + language: 'c', +) + + +c = meson.get_compiler('c') +conf = configuration_data() +pcp_inc = include_directories('src', 'libpcp') + + +if host_machine.system().startswith('freebsd') + pcp_inc = include_directories('.', '/usr/local/include') + add_project_link_arguments('LDFLAGS=/usr/local/lib') +endif + + + +# check for funcs. +foreach func : ['getopt', 'fdopen', 'fgetc', 'getenv', 'getpass', 'arc4random', 'fopen', 'fread', 'fwrite', 'ftruncate', 'fprintf', 'isatty', 'malloc', 'memset', 'memcpy', 'perror', 'posix_memalign', 'setrlimit', 'strnlen', 'strlen', 'strtol', 'tcgetattr', 'umask', 'towlower', 'getopt', 'getopt_long', 'vasprintf',] + conf.set('HAVE_'+func.to_upper(), + c.has_function( + func, + prefix : '#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include ', + ) + ) +endforeach + +if host_machine.system().startswith('freebsd') + conf.set('HAVE_STRNSTR', + c.has_function( + 'strnstr', + prefix: '#include ' + )) +else + bsd = c.find_library('bsd') + conf.set('HAVE_STRNSTR', + c.has_function( + 'strnstr', + prefix: '#include ', + dependencies: bsd, + )) + add_project_dependencies(bsd, language: 'c') +endif + + +# check commandline options +prefix = get_option('prefix') + +if get_option('buildtype') == 'debug' + conf.set('DEBUG', '1') +endif + + + +# setup conf map +version = '@0@'.format(meson.project_version()) + +conf.set('prefix', prefix) +conf.set('VERSION', version) + +subdir('libpcp') + + + + +# code +pcp_sources = files( + 'src/compat_getopt.c', + 'src/encryption.c', + 'src/keymgmt.c', + 'src/keyprint.c', + 'src/pcp.c', + 'src/signature.c', + 'src/z85util.c' +) + + +executable( + 'pcp', + [pcp_sources], + include_directories: [pcp_inc], + dependencies: [libpcp_dep, jansson], + install: true +) + +# build manual page +pod2man = find_program('pod2man', native: true) +if pod2man.found() + res = run_command(pod2man.full_path(), 'man/pcp.pod', 'pcp.1', check:true) + if res.returncode() == 0 + install_man('pcp.1') + endif +endif + + +subdir('tests') diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 0000000..e62869c --- /dev/null +++ b/meson_options.txt @@ -0,0 +1 @@ +# custom build options diff --git a/src/compat_getopt.h b/src/compat_getopt.h index c0c94d2..428c003 100644 --- a/src/compat_getopt.h +++ b/src/compat_getopt.h @@ -26,11 +26,9 @@ #ifndef MY_GETOPT_H_INCLUDED #define MY_GETOPT_H_INCLUDED -#ifdef HAVE_CONFIG_H #include "config.h" -#endif -#if defined(HAVE_GETOPT_H) && defined(HAVE_GETOPT_LONG) +#if defined(HAVE_GETOPT) && defined(HAVE_GETOPT_LONG) #include #else @@ -51,7 +49,7 @@ extern "C" { #define optarg my_optarg /* UNIX-style short-argument parser */ -extern int my_getopt(int argc, char * argv[], const char *opts); +extern int my_getopt(int argc, char *argv[], const char *opts); extern int my_optind, my_opterr, my_optopt; extern char *my_optarg; @@ -72,15 +70,15 @@ struct option { #define optional_argument 2 /* GNU-style long-argument parsers */ -extern int my_getopt_long(int argc, char * argv[], const char *shortopts, - const struct option *longopts, int *longind); +extern int my_getopt_long(int argc, char *argv[], const char *shortopts, + const struct option *longopts, int *longind); -extern int my_getopt_long_only(int argc, char * argv[], const char *shortopts, - const struct option *longopts, int *longind); +extern int my_getopt_long_only(int argc, char *argv[], const char *shortopts, + const struct option *longopts, int *longind); -extern int _my_getopt_internal(int argc, char * argv[], const char *shortopts, - const struct option *longopts, int *longind, - int long_only); +extern int _my_getopt_internal(int argc, char *argv[], const char *shortopts, + const struct option *longopts, int *longind, + int long_only); #ifdef __cplusplus } diff --git a/src/encryption.h b/src/encryption.h index 922f4ce..39a9b51 100644 --- a/src/encryption.h +++ b/src/encryption.h @@ -19,27 +19,28 @@ You can contact me by mail: . */ - #ifndef _HAVE_ENCRYPTION_H #define _HAVE_ENCRYPTION_H #include #include +#include "context.h" +#include "crypto.h" #include "defines.h" #include "key.h" -#include "crypto.h" +#include "keyhash.h" +#include "keyprint.h" #include "pcp.h" +#include "pcpstream.h" +#include "plist.h" #include "uthash.h" #include "z85.h" -#include "keyprint.h" -#include "keyhash.h" -#include "plist.h" -#include "pcpstream.h" -#include "context.h" -int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, int verify); -int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, plist_t *recipient, int signcrypt, int armor, int anon); +int pcpdecrypt(char *id, int useid, char *infile, char *outfile, char *passwd, + int verify); +int pcpencrypt(char *id, char *infile, char *outfile, char *passwd, + plist_t *recipient, int signcrypt, int armor, int anon); void pcpchecksum(char **files, int filenum, char *key); #endif /* _HAVE_ENCRYPTION_H */ diff --git a/src/keymgmt.c b/src/keymgmt.c index 7989243..b17cb1f 100644 --- a/src/keymgmt.c +++ b/src/keymgmt.c @@ -19,10 +19,8 @@ You can contact me by mail: . */ - #include "keymgmt.h" - char *pcp_getstdin(const char *prompt) { char line[255]; char *out = NULL; @@ -43,137 +41,127 @@ char *pcp_getstdin(const char *prompt) { return out; - errgst: +errgst: return NULL; } -int pcp_storekey (pcp_key_t *key) { - if(vault->isnew == 1 || pcphash_count(ptx) == 0) { +int pcp_storekey(pcp_key_t *key) { + if (vault->isnew == 1 || pcphash_count(ptx) == 0) { key->type = PCP_KEY_TYPE_MAINSECRET; } - if(pcpvault_addkey(ptx, vault, key, key->type) == 0) { - if(vault->isnew) + if (pcpvault_addkey(ptx, vault, key, key->type) == 0) { + if (vault->isnew) fprintf(stderr, "new vault created, "); fprintf(stderr, "key 0x%s added to %s.\n", key->id, vault->filename); return 0; } - + return 1; } void pcp_keygen(char *passwd) { - pcp_key_t *k = pcpkey_new (); + pcp_key_t *k = pcpkey_new(); pcp_key_t *key = NULL; - char *owner = pcp_getstdin("Enter the name of the key owner"); - if(owner != NULL) + char *owner = pcp_getstdin("Enter the name of the key owner"); + if (owner != NULL) memcpy(k->owner, owner, strlen(owner) + 1); char *mail = pcp_getstdin("Enter the email address of the key owner"); - if(mail != NULL) + if (mail != NULL) memcpy(k->mail, _lc(mail), strlen(mail) + 1); - if(debug) - pcp_dumpkey(k); + if (debug) + pcp_dumpkey(k); char *passphrase; - if(passwd == NULL) { - pcp_readpass(ptx, &passphrase, - "Enter passphrase for key encryption", + if (passwd == NULL) { + pcp_readpass(ptx, &passphrase, "Enter passphrase for key encryption", "Enter the passphrase again", 1, NULL); - } - else { + } else { passphrase = passwd; } - if(strnlen(passphrase, 1024) > 0) { + if (strnlen(passphrase, 1024) > 0) { double ent = pcp_getentropy(passphrase); - if(ent < 3.32) { - fprintf(stderr, "WARNING: you are using a weak passphrase (entropy: %lf)!\n", ent); + if (ent < 3.32) { + fprintf(stderr, + "WARNING: you are using a weak passphrase (entropy: %lf)!\n", + ent); char *yes = pcp_getstdin("Are you sure to use it [yes|NO]?"); - if(strncmp(yes, "yes", 1024) != 0) { + if (strncmp(yes, "yes", 1024) != 0) { goto errkg1; } } key = pcpkey_encrypt(ptx, k, passphrase); - } - else { + } else { /* No unencrypted secret key allowed anymore [19.08.2015, tom] */ memset(k, 0, sizeof(pcp_key_t)); free(k); goto errkg1; } - if(key != NULL) { + if (key != NULL) { fprintf(stderr, "Generated new secret key:\n"); - if(pcp_storekey(key) == 0) { + if (pcp_storekey(key) == 0) { pcpkey_printshortinfo(key); memset(key, 0, sizeof(pcp_key_t)); free(key); } } - if(passwd == NULL) { + if (passwd == NULL) { /* if passwd is set, it'll be free'd in main() */ sfree(passphrase); } - - errkg1: + +errkg1: free(mail); free(owner); } - void pcp_listkeys() { pcp_key_t *k; int nkeys = pcphash_count(ptx) + pcphash_countpub(ptx); - if(nkeys > 0) { - printf("Key ID Type Creation Time Owner\n"); + if (nkeys > 0) { + printf( + "Key ID Type Creation Time Owner\n"); - pcphash_iterate(ptx, k) { - pcpkey_printlineinfo(k); - } + pcphash_iterate(ptx, k) { pcpkey_printlineinfo(k); } pcp_pubkey_t *p; - pcphash_iteratepub(ptx, p) { - pcppubkey_printlineinfo(p); - } - } - else { - fatal(ptx, "The key vault file %s doesn't contain any keys so far.\n", vault->filename); + pcphash_iteratepub(ptx, p) { pcppubkey_printlineinfo(p); } + } else { + fatal(ptx, "The key vault file %s doesn't contain any keys so far.\n", + vault->filename); } } - char *pcp_normalize_id(char *keyid) { char *id = ucmalloc(17); int len = strnlen(keyid, 24); - if(len == 16) { + if (len == 16) { memcpy(id, keyid, 17); - } - else if(len < 16) { + } else if (len < 16) { fatal(ptx, "Specified key id %s is too short!\n", keyid); free(id); return NULL; - } - else if(len > 18) { + } else if (len > 18) { fatal(ptx, "Specified key id %s is too long!\n", keyid); free(id); return NULL; - } - else { - if(keyid[0] == '0' && keyid[1] == 'x' && len == 18) { + } else { + if (keyid[0] == '0' && keyid[1] == 'x' && len == 18) { int i; - for(i=0; i<16; ++i) { - id[i] = keyid[i+2]; + for (i = 0; i < 16; ++i) { + id[i] = keyid[i + 2]; } id[16] = 0; - } - else { + } else { fatal(ptx, "Specified key id %s is too long!\n", keyid); free(id); return NULL; @@ -186,253 +174,239 @@ char *pcp_normalize_id(char *keyid) { pcp_key_t *pcp_find_primary_secret() { pcp_key_t *k; pcphash_iterate(ptx, k) { - if(k->type == PCP_KEY_TYPE_MAINSECRET) { + if (k->type == PCP_KEY_TYPE_MAINSECRET) { return k; } } /* no primary? whoops */ int nkeys = pcphash_count(ptx); - if(nkeys == 1) { - pcphash_iterate(ptx, k) { - return k; - } + if (nkeys == 1) { + pcphash_iterate(ptx, k) { return k; } } return NULL; } -void pcp_exportsecret(char *keyid, int useid, char *outfile, int armor, char *passwd) { +void pcp_exportsecret(char *keyid, int useid, char *outfile, int armor, + char *passwd) { pcp_key_t *key = NULL; - if(useid == 1) { + if (useid == 1) { /* look if we've got that one */ key = pcphash_keyexists(ptx, keyid); - if(key == NULL) { - fatal(ptx, "Could not find a secret key with id 0x%s in vault %s!\n", keyid, vault->filename); + if (key == NULL) { + fatal(ptx, "Could not find a secret key with id 0x%s in vault %s!\n", + keyid, vault->filename); goto errexpse1; } - } - else { + } else { /* look for our primary key */ key = pcp_find_primary_secret(); - if(key == NULL) { - fatal(ptx, "There's no primary secret key in the vault %s!\n", vault->filename); + if (key == NULL) { + fatal(ptx, "There's no primary secret key in the vault %s!\n", + vault->filename); goto errexpse1; } } FILE *out; - if(outfile == NULL) { + if (outfile == NULL) { out = stdout; - } - else { - if((out = fopen(outfile, "wb+")) == NULL) { + } else { + if ((out = fopen(outfile, "wb+")) == NULL) { fatal(ptx, "Could not create output file %s\n", outfile); - goto errexpse1; + goto errexpse1; } } - - if(out != NULL) { - if(debug) + + if (out != NULL) { + if (debug) pcp_dumpkey(key); - if(passwd == NULL) { + if (passwd == NULL) { char *passphrase; pcp_readpass(ptx, &passphrase, - "Enter passphrase to decrypt your secret key", NULL, 1, NULL); + "Enter passphrase to decrypt your secret key", NULL, 1, + NULL); key = pcpkey_decrypt(ptx, key, passphrase); - if(key == NULL) { + if (key == NULL) { sfree(passphrase); goto errexpse1; } sfree(passphrase); - } - else { + } else { key = pcpkey_decrypt(ptx, key, passwd); - if(key == NULL) { + if (key == NULL) { goto errexpse1; } } Buffer *exported_sk; - if(passwd != NULL) { + if (passwd != NULL) { exported_sk = pcp_export_secret(ptx, key, passwd); - } - else { + } else { char *passphrase; pcp_readpass(ptx, &passphrase, - "Enter passphrase to encrypt the exported secret key", + "Enter passphrase to encrypt the exported secret key", "Repeat passphrase", 1, NULL); exported_sk = pcp_export_secret(ptx, key, passphrase); sfree(passphrase); } - if(exported_sk != NULL) { - if(armor == 1) { + if (exported_sk != NULL) { + if (armor == 1) { size_t zlen; - char *z85 = pcp_z85_encode(buffer_get(exported_sk), buffer_size(exported_sk), &zlen, 1); + char *z85 = pcp_z85_encode(buffer_get(exported_sk), + buffer_size(exported_sk), &zlen, 1); fprintf(out, "%s\r\n%s\r\n%s\r\n", EXP_SK_HEADER, z85, EXP_SK_FOOTER); free(z85); - } - else { + } else { fwrite(buffer_get(exported_sk), 1, buffer_size(exported_sk), out); } buffer_free(exported_sk); fprintf(stderr, "secret key exported.\n"); } - } - errexpse1: - ; +errexpse1:; } - /* if id given, look if it is already a public and export this, else we look for a secret key with that id. without a given keyid we use the primary key. if no keyid has been given but a recipient instead, we try to look up the vault for a match. */ -void pcp_exportpublic(char *keyid, char *passwd, char *outfile, int format, int armor) { +void pcp_exportpublic(char *keyid, char *passwd, char *outfile, int format, + int armor) { FILE *out; int is_foreign = 0; pcp_pubkey_t *pk = NULL; pcp_key_t *sk = NULL; Buffer *exported_pk = NULL; - if(outfile == NULL) { + if (outfile == NULL) { out = stdout; - } - else { - if((out = fopen(outfile, "wb+")) == NULL) { + } else { + if ((out = fopen(outfile, "wb+")) == NULL) { fatal(ptx, "Could not create output file %s\n", outfile); goto errpcpexpu1; } } - if(keyid != NULL) { + if (keyid != NULL) { /* keyid specified, check if it exists and if yes, what type it is */ pk = pcphash_pubkeyexists(ptx, keyid); - if(pk == NULL) { + if (pk == NULL) { /* ok, so, then look for a secret key with that id */ sk = pcphash_keyexists(ptx, keyid); - if(sk == NULL) { - fatal(ptx, "Could not find a key with id 0x%s in vault %s!\n", - keyid, vault->filename); + if (sk == NULL) { + fatal(ptx, "Could not find a key with id 0x%s in vault %s!\n", keyid, + vault->filename); goto errpcpexpu1; - } - else { + } else { /* ok, so it's our own key */ is_foreign = 0; } - } - else { + } else { /* it's a foreign public key, we cannot sign it ourselfes */ is_foreign = 1; } - } - else { + } else { /* we use our primary key anyway */ sk = pcp_find_primary_secret(); - if(sk == NULL) { - fatal(ptx, "There's no primary secret key in the vault %s!\n", vault->filename); + if (sk == NULL) { + fatal(ptx, "There's no primary secret key in the vault %s!\n", + vault->filename); goto errpcpexpu1; } is_foreign = 0; } - - if(is_foreign == 0 && sk->secret[0] == 0 && format <= EXP_FORMAT_PBP) { + if (is_foreign == 0 && sk->secret[0] == 0 && format <= EXP_FORMAT_PBP) { /* decrypt the secret key */ - if(passwd != NULL) { + if (passwd != NULL) { sk = pcpkey_decrypt(ptx, sk, passwd); - } - else { + } else { char *passphrase; pcp_readpass(ptx, &passphrase, - "Enter passphrase to decrypt your secret key", NULL, 1, NULL); + "Enter passphrase to decrypt your secret key", NULL, 1, + NULL); sk = pcpkey_decrypt(ptx, sk, passphrase); sfree(passphrase); } - if(sk == NULL) { + if (sk == NULL) { goto errpcpexpu1; } } /* now, we're ready for the actual export */ - if(format == EXP_FORMAT_NATIVE) { - if(is_foreign == 0) { + if (format == EXP_FORMAT_NATIVE) { + if (is_foreign == 0) { exported_pk = pcp_export_rfc_pub(ptx, sk); - if(exported_pk != NULL) { - if(armor == 1) { + if (exported_pk != NULL) { + if (armor == 1) { size_t zlen; - char *z85 = pcp_z85_encode(buffer_get(exported_pk), buffer_size(exported_pk), &zlen, 1); + char *z85 = pcp_z85_encode(buffer_get(exported_pk), + buffer_size(exported_pk), &zlen, 1); fprintf(out, "%s\r\n%s\r\n%s\r\n", EXP_PK_HEADER, z85, EXP_PK_FOOTER); free(z85); - } - else + } else fwrite(buffer_get(exported_pk), 1, buffer_size(exported_pk), out); buffer_free(exported_pk); fprintf(stderr, "public key exported.\n"); } - } - else { + } else { /* FIXME: export foreign keys unsupported yet */ - fatal(ptx, "Exporting foreign public keys in native format unsupported yet\n"); + fatal(ptx, + "Exporting foreign public keys in native format unsupported yet\n"); goto errpcpexpu1; } - } - else if(format == EXP_FORMAT_PBP) { - if(is_foreign == 0) { + } else if (format == EXP_FORMAT_PBP) { + if (is_foreign == 0) { exported_pk = pcp_export_pbp_pub(sk); - if(exported_pk != NULL) { + if (exported_pk != NULL) { /* PBP format requires armoring always */ size_t zlen; - char *z85pbp = pcp_z85_encode(buffer_get(exported_pk), buffer_size(exported_pk), &zlen, 1); + char *z85pbp = pcp_z85_encode(buffer_get(exported_pk), + buffer_size(exported_pk), &zlen, 1); fprintf(out, "%s", z85pbp); free(z85pbp); buffer_free(exported_pk); fprintf(stderr, "public key exported in PBP format.\n"); } - } - else { + } else { fatal(ptx, "Exporting foreign public keys in PBP format not possible\n"); goto errpcpexpu1; } } - errpcpexpu1: - ; +errpcpexpu1:; } - - void pcpdelete_key(char *keyid) { pcp_pubkey_t *p = pcphash_pubkeyexists(ptx, keyid); - - if(p != NULL) { + + if (p != NULL) { /* delete public */ pcp_keysig_t *sig = pcphash_keysigexists(ptx, keyid); - if(sig != NULL) { + if (sig != NULL) { /* also delete associted sig, if any */ pcphash_del(ptx, sig, sig->type); } pcphash_del(ptx, p, p->type); vault->unsafed = 1; fprintf(stderr, "Public key deleted.\n"); - } - else { + } else { pcp_key_t *s = pcphash_keyexists(ptx, keyid); - if(s != NULL) { + if (s != NULL) { /* delete secret */ pcphash_del(ptx, s, s->type); vault->unsafed = 1; fprintf(stderr, "Secret key deleted.\n"); - } - else { + } else { fatal(ptx, "No key with id 0x%s found!\n", keyid); } } @@ -441,51 +415,56 @@ void pcpdelete_key(char *keyid) { void pcpedit_key(char *keyid) { pcp_key_t *key = pcphash_keyexists(ptx, keyid); - if(key != NULL) { - if(key->secret[0] == 0) { + if (key != NULL) { + if (key->secret[0] == 0) { char *passphrase; - pcp_readpass(ptx, &passphrase, "Enter passphrase to decrypt the key", NULL, 1, NULL); + pcp_readpass(ptx, &passphrase, "Enter passphrase to decrypt the key", + NULL, 1, NULL); key = pcpkey_decrypt(ptx, key, passphrase); sfree(passphrase); } - if(key != NULL) { + if (key != NULL) { fprintf(stderr, "Current owner: %s\n", key->owner); - char *owner = pcp_getstdin(" enter new name or press enter to keep current"); - if(strlen(owner) > 0) + char *owner = + pcp_getstdin(" enter new name or press enter to keep current"); + if (strlen(owner) > 0) memcpy(key->owner, owner, strlen(owner) + 1); fprintf(stderr, "Current mail: %s\n", key->mail); - char *mail = pcp_getstdin(" enter new email or press enter to keep current"); - if(strlen(mail) > 0) + char *mail = + pcp_getstdin(" enter new email or press enter to keep current"); + if (strlen(mail) > 0) memcpy(key->mail, mail, strlen(mail) + 1); free(owner); free(mail); - if(key->type != PCP_KEY_TYPE_MAINSECRET) { + if (key->type != PCP_KEY_TYPE_MAINSECRET) { pcp_key_t *other = NULL; uint8_t haveprimary = 0; pcphash_iterate(ptx, other) { - if(other->type == PCP_KEY_TYPE_MAINSECRET) { + if (other->type == PCP_KEY_TYPE_MAINSECRET) { haveprimary = 1; break; } } char *yes = NULL; - if(! haveprimary) { - fprintf(stderr, "There is currently no primary secret in your vault,\n"); + if (!haveprimary) { + fprintf(stderr, + "There is currently no primary secret in your vault,\n"); yes = pcp_getstdin("want to make this one the primary [yes|NO]?"); - } - else { - fprintf(stderr, "The key %s is currently the primary secret,\n", other->id); - yes = pcp_getstdin("want to make this one the primary instead [yes|NO]?"); + } else { + fprintf(stderr, "The key %s is currently the primary secret,\n", + other->id); + yes = pcp_getstdin( + "want to make this one the primary instead [yes|NO]?"); } - if(strncmp(yes, "yes", 1024) == 0) { + if (strncmp(yes, "yes", 1024) == 0) { key->type = PCP_KEY_TYPE_MAINSECRET; - if(haveprimary) { + if (haveprimary) { fprintf(stderr, "other type: %d\n", other->type); other->type = PCP_KEY_TYPE_SECRET; fprintf(stderr, " new type: %d\n", other->type); @@ -496,40 +475,39 @@ void pcpedit_key(char *keyid) { char *passphrase; pcp_readpass(ptx, &passphrase, - "Enter new passphrase for key encryption (press enter to keep current)", + "Enter new passphrase for key encryption (press enter to " + "keep current)", "Enter the passphrase again", 1, NULL); - if(strnlen(passphrase, 1024) > 0) { + if (strnlen(passphrase, 1024) > 0) { key = pcpkey_encrypt(ptx, key, passphrase); sfree(passphrase); } - if(key != NULL) { - if(debug) + if (key != NULL) { + if (debug) pcp_dumpkey(key); vault->unsafed = 1; /* will be safed automatically */ fprintf(stderr, "Key %s changed.\n", key->id); } } - } - else { + } else { fatal(ptx, "No key with id 0x%s found!\n", keyid); } } - char *pcp_find_id_byrec(char *recipient) { pcp_pubkey_t *p; char *id = NULL; _lc(recipient); pcphash_iteratepub(ptx, p) { - if(strncmp(p->owner, recipient, 255) == 0) { + if (strncmp(p->owner, recipient, 255) == 0) { id = ucmalloc(17); strncpy(id, p->id, 17); break; } - if(strncmp(p->mail, recipient, 255) == 0) { + if (strncmp(p->mail, recipient, 255) == 0) { id = ucmalloc(17); strncpy(id, p->id, 17); break; @@ -538,8 +516,7 @@ char *pcp_find_id_byrec(char *recipient) { return id; } - -int pcp_import (vault_t *vault, FILE *in, char *passwd) { +int pcp_import(vault_t *vault, FILE *in, char *passwd) { byte *buf = ucmalloc(PCP_BLOCK_SIZE); size_t bufsize; pcp_pubkey_t *pub = NULL; @@ -553,97 +530,95 @@ int pcp_import (vault_t *vault, FILE *in, char *passwd) { bufsize = ps_read(pin, buf, PCP_BLOCK_SIZE); - if(bufsize == 0) { + if (bufsize == 0) { fatal(ptx, "Input file is empty!\n"); goto errimp1; } /* first try as rfc pub key */ bundle = pcp_import_binpub(ptx, buf, bufsize); - if(bundle != NULL) { + if (bundle != NULL) { keysig = bundle->s; pub = bundle->p; - if(debug) + if (debug) pcp_dumppubkey(pub); - if(keysig == NULL) { + if (keysig == NULL) { fatals_ifany(ptx); - char *yes = pcp_getstdin("WARNING: signature doesn't verify, import anyway [yes|NO]?"); - if(strncmp(yes, "yes", 1024) != 0) { + char *yes = pcp_getstdin( + "WARNING: signature doesn't verify, import anyway [yes|NO]?"); + if (strncmp(yes, "yes", 1024) != 0) { free(yes); goto errimp2; } free(yes); } - if(pcp_sanitycheck_pub(ptx, pub) == 0) { - if(pcpvault_addkey(ptx, vault, (void *)pub, PCP_KEY_TYPE_PUBLIC) == 0) { + if (pcp_sanitycheck_pub(ptx, pub) == 0) { + if (pcpvault_addkey(ptx, vault, (void *)pub, PCP_KEY_TYPE_PUBLIC) == 0) { fprintf(stderr, "key 0x%s added to %s.\n", pub->id, vault->filename); /* avoid double free */ success = 0; - } - else + } else goto errimp2; - - if(keysig != NULL) { - if(pcpvault_addkey(ptx, vault, keysig, keysig->type) != 0) { + + if (keysig != NULL) { + if (pcpvault_addkey(ptx, vault, keysig, keysig->type) != 0) { /* FIXME: remove pubkey if storing the keysig failed */ goto errimp2; } } - } - else + } else goto errimp2; - } - else { + } else { /* it's not public key, so let's try to interpret it as secret key */ - if(ptx->verbose) + if (ptx->verbose) fatals_ifany(ptx); - if(passwd != NULL) { + if (passwd != NULL) { sk = pcp_import_secret(ptx, buf, bufsize, passwd); - } - else { + } else { char *passphrase; pcp_readpass(ptx, &passphrase, - "Enter passphrase to decrypt the secret key file", NULL, 1, NULL); + "Enter passphrase to decrypt the secret key file", NULL, 1, + NULL); sk = pcp_import_secret(ptx, buf, bufsize, passphrase); sfree(passphrase); } - if(sk == NULL) { + if (sk == NULL) { goto errimp2; } - if(debug) + if (debug) pcp_dumpkey(sk); pcp_key_t *maybe = pcphash_keyexists(ptx, sk->id); - if(maybe != NULL) { - fatal(ptx, "Secretkey sanity check: there already exists a key with the id 0x%s\n", sk->id); + if (maybe != NULL) { + fatal(ptx, + "Secretkey sanity check: there already exists a key with the id " + "0x%s\n", + sk->id); goto errimp2; } /* store it */ - if(passwd != NULL) { + if (passwd != NULL) { sk = pcpkey_encrypt(ptx, sk, passwd); - } - else { + } else { char *passphrase; - pcp_readpass(ptx, &passphrase, - "Enter passphrase for key encryption", + pcp_readpass(ptx, &passphrase, "Enter passphrase for key encryption", "Enter the passphrase again", 1, NULL); - - if(strnlen(passphrase, 1024) > 0) { + + if (strnlen(passphrase, 1024) > 0) { /* encrypt the key */ sk = pcpkey_encrypt(ptx, sk, passphrase); sfree(passphrase); - } - else { + } else { /* ask for confirmation if we shall store it in the clear */ - char *yes = pcp_getstdin( - "WARNING: secret key will be stored unencrypted. Are you sure [yes|NO]?"); - if(strncmp(yes, "yes", 1024) != 0) { + char *yes = pcp_getstdin("WARNING: secret key will be stored " + "unencrypted. Are you sure [yes|NO]?"); + if (strncmp(yes, "yes", 1024) != 0) { free(yes); goto errimp1; } @@ -651,39 +626,38 @@ int pcp_import (vault_t *vault, FILE *in, char *passwd) { } } - if(sk != NULL) { + if (sk != NULL) { /* store it to the vault if we got it til here */ - if(pcp_sanitycheck_key(ptx, sk) == 0) { - if(pcp_storekey(sk) == 0) { - pcpkey_printshortinfo(sk); + if (pcp_sanitycheck_key(ptx, sk) == 0) { + if (pcp_storekey(sk) == 0) { + pcpkey_printshortinfo(sk); success = 0; } } } } - errimp2: - if(keysig != NULL) { + if (keysig != NULL) { ucfree(keysig->blob, keysig->size); ucfree(keysig, sizeof(pcp_keysig_t)); } - - if(bundle != NULL) { + + if (bundle != NULL) { free(bundle); } - - if(pub != NULL) { + + if (pub != NULL) { ucfree(pub, sizeof(pcp_pubkey_t)); } - - if(sk != NULL) { + + if (sk != NULL) { ucfree(sk, sizeof(pcp_key_t)); } ucfree(buf, bufsize); - errimp1: +errimp1: ps_close(pin); return success; diff --git a/src/keymgmt.h b/src/keymgmt.h index b907177..95ccc8b 100644 --- a/src/keymgmt.h +++ b/src/keymgmt.h @@ -19,44 +19,44 @@ You can contact me by mail: . */ - #ifndef _HAVE_KEYMGMT_H #define _HAVE_KEYMGMT_H -#include #include #include #include +#include #include -#include "randomart.h" -#include "key.h" -#include "pcp.h" -#include "vault.h" -#include "defines.h" -#include "readpass.h" -#include "keyprint.h" -#include "keyhash.h" -#include "util.h" #include "buffer.h" -#include "mgmt.h" #include "context.h" +#include "defines.h" +#include "key.h" +#include "keyhash.h" +#include "keyprint.h" +#include "mgmt.h" +#include "randomart.h" +#include "readpass.h" +#include "util.h" +#include "vault.h" #define _WITH_GETLINE char *pcp_getstdin(const char *prompt); -int pcp_storekey (pcp_key_t *key); +int pcp_storekey(pcp_key_t *key); void pcp_keygen(char *passwd); void pcp_listkeys(); -void pcp_exportsecret(char *keyid, int useid, char *outfile, int armor, char *passwd); -void pcp_exportpublic(char *keyid, char *passwd, char *outfile, int format, int armor); +void pcp_exportsecret(char *keyid, int useid, char *outfile, int armor, + char *passwd); +void pcp_exportpublic(char *keyid, char *passwd, char *outfile, int format, + int armor); pcp_key_t *pcp_getrsk(pcp_key_t *s, char *recipient, char *passwd); char *pcp_normalize_id(char *keyid); pcp_key_t *pcp_find_primary_secret(); -int pcp_import (vault_t *vault, FILE *in, char *passwd); +int pcp_import(vault_t *vault, FILE *in, char *passwd); void pcpdelete_key(char *keyid); char *pcp_find_id_byrec(char *recipient); diff --git a/src/pcp.c b/src/pcp.c index 53151f1..9645c17 100644 --- a/src/pcp.c +++ b/src/pcp.c @@ -19,43 +19,45 @@ You can contact me by mail: . */ - #include "pcp.h" #include "defines.h" +vault_t *vault; +PCPCTX *ptx; +int debug; + void usage(int error) { fprintf(stderr, PCP_HELP_INTRO); - if(error == 0) + if (error == 0) fprintf(stderr, PCP_HELP); version(); exit(EXIT_FAILURE); } - void version() { fprintf(stderr, "pcp version %d.%d.%d, use --help to learn how to use.\n", PCP_VERSION_MAJOR, PCP_VERSION_MINOR, PCP_VERSION_PATCH); exit(0); } - char *default_vault() { - char *path = ucmalloc(1024);; + char *path = ucmalloc(1024); + ; snprintf(path, 1024, "%s/.pcpvault", getenv("HOME")); - return path; + return path; } char *altin(char *infile, int stdinused) { - if(infile == NULL && stdinused == 1) { + if (infile == NULL && stdinused == 1) { fprintf(stderr, "Error: cannot use because -X had precedence!\n"); exit(1); } return infile; } -int main (int argc, char **argv) { - int opt, mode, usevault, useid, userec, lo, armor, detach, \ - signcrypt, exportformat, anon, xpf; +int main(int argc, char **argv) { + int opt, mode, usevault, useid, userec, lo, armor, detach, signcrypt, + exportformat, anon, xpf; char *vaultfile = default_vault(); char *outfile = NULL; char *infile = NULL; @@ -86,290 +88,288 @@ int main (int argc, char **argv) { ptx = ptx_new(); static struct option longopts[] = { - /* generics */ - { "vault", required_argument, NULL, 'V' }, - { "outfile", required_argument, NULL, 'O' }, - { "infile", required_argument, NULL, 'I' }, - { "keyid", required_argument, NULL, 'i' }, - { "text", required_argument, NULL, 't' }, - { "xpass", required_argument, NULL, 'x' }, - { "password-file", required_argument, NULL, 'X' }, - { "extpass", required_argument, NULL, LONG_EXTPASS }, - { "recipient", required_argument, NULL, 'r' }, + /* generics */ + {"vault", required_argument, NULL, 'V'}, + {"outfile", required_argument, NULL, 'O'}, + {"infile", required_argument, NULL, 'I'}, + {"keyid", required_argument, NULL, 'i'}, + {"text", required_argument, NULL, 't'}, + {"xpass", required_argument, NULL, 'x'}, + {"password-file", required_argument, NULL, 'X'}, + {"extpass", required_argument, NULL, LONG_EXTPASS}, + {"recipient", required_argument, NULL, 'r'}, - /* key management */ - { "keygen", no_argument, NULL, 'k' }, - { "listkeys", no_argument, NULL, 'l' }, - { "listkeys-verbose",no_argument, NULL, 'L' }, /* alias for -l -v */ - { "export-secret", no_argument, NULL, 's' }, - { "export-public", no_argument, NULL, 'p' }, - { "export", no_argument, NULL, 'p' }, /* alias -p */ - { "import", no_argument, NULL, 'K' }, /* alias -P */ - { "import-key", no_argument, NULL, 'K' }, /* alias -K */ - { "remove-key", no_argument, NULL, 'R' }, - { "edit-key", no_argument, NULL, 'E' }, - { "export-format", required_argument, NULL, 'F' }, + /* key management */ + {"keygen", no_argument, NULL, 'k'}, + {"listkeys", no_argument, NULL, 'l'}, + {"listkeys-verbose", no_argument, NULL, 'L'}, /* alias for -l -v */ + {"export-secret", no_argument, NULL, 's'}, + {"export-public", no_argument, NULL, 'p'}, + {"export", no_argument, NULL, 'p'}, /* alias -p */ + {"import", no_argument, NULL, 'K'}, /* alias -P */ + {"import-key", no_argument, NULL, 'K'}, /* alias -K */ + {"remove-key", no_argument, NULL, 'R'}, + {"edit-key", no_argument, NULL, 'E'}, + {"export-format", required_argument, NULL, 'F'}, - /* crypto */ - { "encrypt", no_argument, NULL, 'e' }, - { "encrypt-sym", no_argument, NULL, 'm' }, - { "decrypt", no_argument, NULL, 'd' }, - { "anonymous", no_argument, NULL, 'A' }, - { "add-myself", no_argument, NULL, 'M' }, - { "checksum", no_argument, NULL, 'C' }, + /* crypto */ + {"encrypt", no_argument, NULL, 'e'}, + {"encrypt-sym", no_argument, NULL, 'm'}, + {"decrypt", no_argument, NULL, 'd'}, + {"anonymous", no_argument, NULL, 'A'}, + {"add-myself", no_argument, NULL, 'M'}, + {"checksum", no_argument, NULL, 'C'}, - /* encoding */ - { "z85-encode", no_argument, NULL, 'z' }, - { "armor", no_argument, NULL, 'a' }, /* alias -z */ - { "textmode", no_argument, NULL, 'a' }, /* alias -z */ - { "z85-decode", no_argument, NULL, 'Z' }, - { "json-io", no_argument, NULL, 'j' }, + /* encoding */ + {"z85-encode", no_argument, NULL, 'z'}, + {"armor", no_argument, NULL, 'a'}, /* alias -z */ + {"textmode", no_argument, NULL, 'a'}, /* alias -z */ + {"z85-decode", no_argument, NULL, 'Z'}, + {"json-io", no_argument, NULL, 'j'}, - /* globals */ - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, '0' }, /* no short opt, FIXME: how to avoid? */ - { "verbose", no_argument, NULL, 'v' }, - { "debug", no_argument, NULL, 'D' }, + /* globals */ + {"help", no_argument, NULL, 'h'}, + {"version", no_argument, NULL, + '0'}, /* no short opt, FIXME: how to avoid? */ + {"verbose", no_argument, NULL, 'v'}, + {"debug", no_argument, NULL, 'D'}, - /* signing */ - { "sign", no_argument, NULL, 'g' }, - { "check-signature", no_argument, NULL, 'c' }, - { "sigfile", required_argument, NULL, 'f' }, - { NULL, 0, NULL, 0 } - }; + /* signing */ + {"sign", no_argument, NULL, 'g'}, + {"check-signature", no_argument, NULL, 'c'}, + {"sigfile", required_argument, NULL, 'f'}, + {NULL, 0, NULL, 0}}; - while ((opt = getopt_long(argc, argv, "klLV:vdehsO:i:I:pSPRtEx:DzaZr:gcmf:b1F:0KAMX:jC", + while ((opt = getopt_long(argc, argv, + "klLV:vdehsO:i:I:pSPRtEx:DzaZr:gcmf:b1F:0KAMX:jC", longopts, NULL)) != -1) { - - switch (opt) { - case 0: - switch(lo) { - case 's': - printf("sign\n"); - break; - } - break; - - case 'k': - mode += PCP_MODE_KEYGEN; - usevault = 1; - break; - case 'L': - ptx->verbose = 1; /* no break by purpose, turn on -l */ - case 'l': - mode += PCP_MODE_LISTKEYS; - usevault = 1; - break; + switch (opt) { + case 0: + switch (lo) { case 's': - mode += PCP_MODE_EXPORT_SECRET; - usevault = 1; - break; - case 'p': - mode += PCP_MODE_EXPORT_PUBLIC; - usevault = 1; - break; - case 'K': - mode += PCP_MODE_IMPORT; - usevault = 1; - break; - case 'R': - mode += PCP_MODE_DELETE_KEY; - usevault = 1; - break; - case 't': - mode += PCP_MODE_TEXT; - usevault = 0; - break; - case 'E': - mode += PCP_MODE_EDIT; - usevault = 1; - break; - case 'e': - mode += PCP_MODE_ENCRYPT; - usevault = 1; - break; - case 'm': - mode += PCP_MODE_ENCRYPT_ME; - break; - case 'd': - mode += PCP_MODE_DECRYPT; - usevault = 1; - break; - case 'z': - case 'a': - armor = 1; - break; - case 'Z': - armor = 2; - break; - case 'A': - anon = 1; - break; - case 'F': - if(strncmp(optarg, "pbp", 3) == 0) { - exportformat = EXP_FORMAT_PBP; - } - else if(strncmp(optarg, "pcp", 3) == 0) { - exportformat = EXP_FORMAT_NATIVE; - } - else { - fprintf(stderr, "WARN: Unknown export format specified, using native\n"); - exportformat = EXP_FORMAT_NATIVE; - } - break; - case 'j': -#ifdef HAVE_JSON - ptx->json = 1; -#else - fprintf(stderr, "WARN: -j set, but no JSON support compiled in. Recompile with --with-json\n"); -#endif - break; - case 'g': - mode += PCP_MODE_SIGN; - usevault = 1; - break; - case 'c': - mode += PCP_MODE_VERIFY; - usevault = 1; - break; - case 'C': - mode += PCP_MODE_CHECKSUM; - break; - case 'f': - sigfile = ucmalloc(strlen(optarg)+1); - strncpy(sigfile, optarg, strlen(optarg)+1); - detach = 1; + printf("sign\n"); break; + } + break; - case 'V': - strncpy(vaultfile, optarg, 1024); - break; - case 'O': - if(strncmp(optarg, "-", 2) > 0) { - outfile = ucmalloc(strlen(optarg)+1); - strncpy(outfile, optarg, strlen(optarg)+1); - } - break; - case 'I': - if(strncmp(optarg, "-", 2) > 0) { - infile = ucmalloc(strlen(optarg)+1); - strncpy(infile, optarg, strlen(optarg)+1); - } - break; - case 'X': - xpassfile = ucmalloc(strlen(optarg)+1); - strncpy(xpassfile, optarg, strlen(optarg)+1); - xpf = 1; - break; - case 'i': - keyid = ucmalloc(19); - strncpy(keyid, optarg, 19); - useid = 1; - break; - case 'x': - xpass = smalloc(strlen(optarg)+1); - strncpy(xpass, optarg, strlen(optarg)+1); - break; - case LONG_EXTPASS: - askpass = malloc(strlen(optarg)+1); - strncpy(askpass, optarg, strlen(optarg)+1); - break; - case 'r': - p_add(&recipient, optarg); - userec = 1; - break; - case 'M': - p_add_me(&recipient); - userec = 1; - break; - case 'D': - debug = 1; - break; - case '0': - version(); - case 'v': - ptx->verbose = 1; - break; - case 'h': - usage(0); - default: - usage(1); + case 'k': + mode += PCP_MODE_KEYGEN; + usevault = 1; + break; + case 'L': + ptx->verbose = 1; /* no break by purpose, turn on -l */ + case 'l': + mode += PCP_MODE_LISTKEYS; + usevault = 1; + break; + + case 's': + mode += PCP_MODE_EXPORT_SECRET; + usevault = 1; + break; + case 'p': + mode += PCP_MODE_EXPORT_PUBLIC; + usevault = 1; + break; + case 'K': + mode += PCP_MODE_IMPORT; + usevault = 1; + break; + case 'R': + mode += PCP_MODE_DELETE_KEY; + usevault = 1; + break; + case 't': + mode += PCP_MODE_TEXT; + usevault = 0; + break; + case 'E': + mode += PCP_MODE_EDIT; + usevault = 1; + break; + case 'e': + mode += PCP_MODE_ENCRYPT; + usevault = 1; + break; + case 'm': + mode += PCP_MODE_ENCRYPT_ME; + break; + case 'd': + mode += PCP_MODE_DECRYPT; + usevault = 1; + break; + case 'z': + case 'a': + armor = 1; + break; + case 'Z': + armor = 2; + break; + case 'A': + anon = 1; + break; + case 'F': + if (strncmp(optarg, "pbp", 3) == 0) { + exportformat = EXP_FORMAT_PBP; + } else if (strncmp(optarg, "pcp", 3) == 0) { + exportformat = EXP_FORMAT_NATIVE; + } else { + fprintf(stderr, + "WARN: Unknown export format specified, using native\n"); + exportformat = EXP_FORMAT_NATIVE; + } + break; + case 'j': +#ifdef HAVE_JSON + ptx->json = 1; +#else + fprintf(stderr, "WARN: -j set, but no JSON support compiled in. " + "Recompile with --with-json\n"); +#endif + break; + case 'g': + mode += PCP_MODE_SIGN; + usevault = 1; + break; + case 'c': + mode += PCP_MODE_VERIFY; + usevault = 1; + break; + case 'C': + mode += PCP_MODE_CHECKSUM; + break; + case 'f': + sigfile = ucmalloc(strlen(optarg) + 1); + strncpy(sigfile, optarg, strlen(optarg) + 1); + detach = 1; + break; + + case 'V': + strncpy(vaultfile, optarg, 1024); + break; + case 'O': + if (strncmp(optarg, "-", 2) > 0) { + outfile = ucmalloc(strlen(optarg) + 1); + strncpy(outfile, optarg, strlen(optarg) + 1); + } + break; + case 'I': + if (strncmp(optarg, "-", 2) > 0) { + infile = ucmalloc(strlen(optarg) + 1); + strncpy(infile, optarg, strlen(optarg) + 1); + } + break; + case 'X': + xpassfile = ucmalloc(strlen(optarg) + 1); + strncpy(xpassfile, optarg, strlen(optarg) + 1); + xpf = 1; + break; + case 'i': + keyid = ucmalloc(19); + strncpy(keyid, optarg, 19); + useid = 1; + break; + case 'x': + xpass = smalloc(strlen(optarg) + 1); + strncpy(xpass, optarg, strlen(optarg) + 1); + break; + case LONG_EXTPASS: + askpass = malloc(strlen(optarg) + 1); + strncpy(askpass, optarg, strlen(optarg) + 1); + break; + case 'r': + p_add(&recipient, optarg); + userec = 1; + break; + case 'M': + p_add_me(&recipient); + userec = 1; + break; + case 'D': + debug = 1; + break; + case '0': + version(); + case 'v': + ptx->verbose = 1; + break; + case 'h': + usage(0); + default: + usage(1); } } argc -= optind; argv += optind; - if(mode == 0) { + if (mode == 0) { /* turn -z|-Z into a mode if there's nothing else specified */ - if(armor == 1) { + if (armor == 1) { mode = PCP_MODE_ZENCODE; - } - else if(armor == 2) { + } else if (armor == 2) { mode = PCP_MODE_ZDECODE; - } - else { + } else { version(); return 1; } } - if(mode == PCP_MODE_ENCRYPT + PCP_MODE_SIGN) { + if (mode == PCP_MODE_ENCRYPT + PCP_MODE_SIGN) { mode = PCP_MODE_ENCRYPT; signcrypt = 1; } - if(mode == PCP_MODE_DECRYPT + PCP_MODE_VERIFY) { + if (mode == PCP_MODE_DECRYPT + PCP_MODE_VERIFY) { mode = PCP_MODE_DECRYPT; signcrypt = 1; } - #ifndef DEBUG -# ifdef HAVE_SETRLIMIT - setrlimit(RLIMIT_CORE, &(struct rlimit) {0, 0}); -# endif -#endif +#ifdef HAVE_SETRLIMIT + setrlimit(RLIMIT_CORE, &(struct rlimit){0, 0}); +#endif +#endif - errno = 0; /* FIXME: workaround for https://github.com/jedisct1/libsodium/issues/114 */ + errno = 0; /* FIXME: workaround for + https://github.com/jedisct1/libsodium/issues/114 */ - if(mode == PCP_MODE_ENCRYPT && useid == 0 && userec == 0) { + if (mode == PCP_MODE_ENCRYPT && useid == 0 && userec == 0) { usevault = 0; mode = PCP_MODE_ENCRYPT_ME; } - if(argc >= 1) { + if (argc >= 1) { /* ok, there are arguments left on the commandline. treat it as filename or recipient, depending on current mode and other given parameters */ - extra = ucmalloc(strlen(argv[0])+1); - strncpy(extra, argv[0], strlen(argv[0])+1); + extra = ucmalloc(strlen(argv[0]) + 1); + strncpy(extra, argv[0], strlen(argv[0]) + 1); int useex = 0; switch (mode) { case PCP_MODE_DECRYPT: - if(infile == NULL) { + if (infile == NULL) { infile = extra; useex = 1; } break; case PCP_MODE_ENCRYPT: - if(infile == NULL) { + if (infile == NULL) { infile = extra; useex = 1; - } - else if(userec == 0 && useid == 0) { + } else if (userec == 0 && useid == 0) { userec = 1; int i; - for (i=0; ipcp_exit; ptx_clean(ptx); - if(infile != NULL) + if (infile != NULL) free(infile); - if(outfile != NULL) + if (outfile != NULL) free(outfile); - if(vaultfile != NULL) + if (vaultfile != NULL) free(vaultfile); - if(sigfile != NULL) + if (sigfile != NULL) free(sigfile); - if(xpass != NULL) + if (xpass != NULL) sfree(xpass); - if(askpass != NULL) + if (askpass != NULL) free(askpass); - if(xpassfile != NULL) + if (xpassfile != NULL) free(xpassfile); - if(recipient != NULL) + if (recipient != NULL) p_clean(recipient); - if(id != NULL) + if (id != NULL) free(id); - if(keyid != NULL) + if (keyid != NULL) free(keyid); return e; } diff --git a/src/pcp.h b/src/pcp.h index 6216d85..56c984e 100644 --- a/src/pcp.h +++ b/src/pcp.h @@ -19,58 +19,58 @@ You can contact me by mail: . */ - #ifndef _HAVE_PCP_H #define _HAVE_PCP_H -#include +#include #include #include -#include +#include #ifndef DEBUG -# ifdef HAVE_SETRLIMIT -# include -# include -# include -# endif +#ifdef HAVE_SETRLIMIT +#include +#include +#include +#endif #endif /* lib */ -#include "mem.h" -#include "z85.h" -#include "zmq_z85.h" -#include "z85util.h" -#include "version.h" -#include "vault.h" #include "context.h" +#include "mem.h" +#include "vault.h" +#include "version.h" +#include "z85.h" +#include "z85util.h" +#include "zmq_z85.h" /* subs */ -#include "keymgmt.h" -#include "usage.h" #include "encryption.h" -#include "signature.h" #include "keyhash.h" +#include "keymgmt.h" #include "plist.h" +#include "signature.h" +#include "usage.h" /* operation modi */ -/* perl -e '$x=0; while ($x<100000) { $x++; $x *= 1.7; printf "0x%08X: %d\n", $x, $x }' */ -#define PCP_MODE_KEYGEN 0x00000001 -#define PCP_MODE_LISTKEYS 0x00000004 +/* perl -e '$x=0; while ($x<100000) { $x++; $x *= 1.7; printf "0x%08X: %d\n", + * $x, $x }' */ +#define PCP_MODE_KEYGEN 0x00000001 +#define PCP_MODE_LISTKEYS 0x00000004 #define PCP_MODE_EXPORT_SECRET 0x00000009 #define PCP_MODE_EXPORT_PUBLIC 0x00000011 -#define PCP_MODE_IMPORT 0x00000020 -#define PCP_MODE_ENCRYPT_ME 0x00000038 -#define PCP_MODE_DELETE_KEY 0x00000061 -#define PCP_MODE_TEXT 0x000000A6 -#define PCP_MODE_EDIT 0x0000011D -#define PCP_MODE_ENCRYPT 0x000001E7 -#define PCP_MODE_DECRYPT 0x0000033D -#define PCP_MODE_ZENCODE 0x00000584 -#define PCP_MODE_ZDECODE 0x00000962 -#define PCP_MODE_SIGN 0x00000FF6 -#define PCP_MODE_VERIFY 0x00001B25 -#define PCP_MODE_CHECKSUM 0x00002E27 +#define PCP_MODE_IMPORT 0x00000020 +#define PCP_MODE_ENCRYPT_ME 0x00000038 +#define PCP_MODE_DELETE_KEY 0x00000061 +#define PCP_MODE_TEXT 0x000000A6 +#define PCP_MODE_EDIT 0x0000011D +#define PCP_MODE_ENCRYPT 0x000001E7 +#define PCP_MODE_DECRYPT 0x0000033D +#define PCP_MODE_ZENCODE 0x00000584 +#define PCP_MODE_ZDECODE 0x00000962 +#define PCP_MODE_SIGN 0x00000FF6 +#define PCP_MODE_VERIFY 0x00001B25 +#define PCP_MODE_CHECKSUM 0x00002E27 /* 0x00001B25 @@ -82,15 +82,16 @@ 0x00028F70 */ -#define PCP_HELP_INTRO "This is Pretty Curved Privacy. Licensed under the GPLv3. This is\n" \ -"BETA software. Use with care. NOT intended for production use.\n" +#define PCP_HELP_INTRO \ + "This is Pretty Curved Privacy. Licensed under the GPLv3. This is\n" \ + "BETA software. Use with care. NOT intended for production use.\n" #define LONG_EXTPASS 515 /* some globals */ -vault_t *vault; -PCPCTX *ptx; -int debug; +extern vault_t *vault; +extern PCPCTX *ptx; +extern int debug; void version(); void usage(); diff --git a/src/z85util.c b/src/z85util.c index 9891925..4a84be4 100644 --- a/src/z85util.c +++ b/src/z85util.c @@ -19,26 +19,25 @@ You can contact me by mail: . */ - #include "z85util.h" int pcpz85_encode(char *infile, char *outfile) { FILE *in; FILE *out; - if(infile == NULL) + if (infile == NULL) in = stdin; else { - if((in = fopen(infile, "rb")) == NULL) { + if ((in = fopen(infile, "rb")) == NULL) { fatal(ptx, "Could not open input file %s\n", infile); goto errz1; } } - if(outfile == NULL) + if (outfile == NULL) out = stdout; else { - if((out = fopen(outfile, "wb+")) == NULL) { + if ((out = fopen(outfile, "wb+")) == NULL) { fatal(ptx, "Could not open output file %s\n", outfile); goto errz1; } @@ -47,18 +46,18 @@ int pcpz85_encode(char *infile, char *outfile) { byte *input = NULL; size_t inputBufSize = 0; byte onebyte[1]; - - while(!feof(in)) { - if(!fread(&onebyte, 1, 1, in)) + + while (!feof(in)) { + if (!fread(&onebyte, 1, 1, in)) break; byte *tmp = realloc(input, inputBufSize + 1); input = tmp; memmove(&input[inputBufSize], onebyte, 1); - inputBufSize ++; + inputBufSize++; } fclose(in); - if(inputBufSize == 0) { + if (inputBufSize == 0) { fatal(ptx, "Input file is empty!\n"); goto errz2; } @@ -66,9 +65,9 @@ int pcpz85_encode(char *infile, char *outfile) { size_t zlen; char *encoded = pcp_z85_encode(input, inputBufSize, &zlen, 1); - if(encoded != NULL) { + if (encoded != NULL) { fprintf(out, "%s\n%s\n%s\n", PCP_ZFILE_HEADER, encoded, PCP_ZFILE_FOOTER); - if(ferror(out) != 0) { + if (ferror(out) != 0) { fatal(ptx, "Failed to write z85 output!\n"); } free(encoded); @@ -77,33 +76,30 @@ int pcpz85_encode(char *infile, char *outfile) { return 0; - errz2: +errz2: free(input); - errz1: +errz1: return 1; } - - - int pcpz85_decode(char *infile, char *outfile) { FILE *in; FILE *out; - if(infile == NULL) + if (infile == NULL) in = stdin; else { - if((in = fopen(infile, "rb")) == NULL) { + if ((in = fopen(infile, "rb")) == NULL) { fatal(ptx, "Could not open input file %s\n", infile); goto errdz1; } } - if(outfile == NULL) + if (outfile == NULL) out = stdout; else { - if((out = fopen(outfile, "wb+")) == NULL) { + if ((out = fopen(outfile, "wb+")) == NULL) { fatal(ptx, "Could not open output file %s\n", outfile); goto errdz1; } @@ -111,20 +107,17 @@ int pcpz85_decode(char *infile, char *outfile) { char *encoded = pcp_readz85file(ptx, in); - if(encoded == NULL) + if (encoded == NULL) goto errdz1; size_t clen; byte *decoded = pcp_z85_decode(ptx, encoded, &clen); - - - if(decoded == NULL) + if (decoded == NULL) goto errdz2; - + fwrite(decoded, clen, 1, out); - fclose(out); - if(ferror(out) != 0) { + if (fclose(out) != 0) { fatal(ptx, "Failed to write decoded output!\n"); goto errdz3; } @@ -133,12 +126,12 @@ int pcpz85_decode(char *infile, char *outfile) { free(decoded); return 0; - errdz3: +errdz3: free(decoded); - errdz2: +errdz2: free(encoded); - errdz1: +errdz1: return 1; } diff --git a/tests/iotests.cfg b/tests/iotests.cfg index 6146aa3..c130439 100644 --- a/tests/iotests.cfg +++ b/tests/iotests.cfg @@ -20,17 +20,20 @@ # You can contact me by mail: . # -pcp=../src/pcp1 +pcp=../pcp vault=v1 passwd=xxx md5msg=66b8c4ca9e5d2a7e3c0559c3cdea3d50 +os=$(uname) . ./keys.cfg check_dependencies_shell () { - cmd="which mdmfs" - expect="/mdmfs/" - check "$cmd" "$expect" "$input" + if test "$os" = "FreeBSD"; then + cmd="which mdmfs" + expect="/mdmfs/" + check "$cmd" "$expect" "$input" + fi } check_dependencies_pcp () { @@ -39,10 +42,16 @@ check_dependencies_pcp () { check "$cmd" "$expect" "$input" } -# this one only works on freebsd for my user. sorrry +# this one only works on freebsd for my user. sorry check_vault_disk_full () { - sudo mdmfs -s 1M -w 1001:1001 md env && dd if=/dev/zero of=env/b bs=1024 count=700 - cmd="./jot 100 | while read N; do if ! (echo a; echo b) | $pcp -V env/v1 -k -x x; then break; fi; done" - expect="/Failed to copy/" - check "$cmd" "$expect" "$input" + if test "$os" = "FreeBSD"; then + sudo mdmfs -s 1M -w 1001:1001 md env && dd if=/dev/zero of=env/b bs=1024 count=700 + cmd="./jot 100 | while read N; do if ! (echo a; echo b) | $pcp -V env/v1 -k -x x; then break; fi; done" + expect="/Failed to copy/" + check "$cmd" "$expect" "$input" + fi +} + +prepare() { + : } diff --git a/tests/jsonunittests.cfg b/tests/jsonunittests.cfg index 06bc92b..673964f 100644 --- a/tests/jsonunittests.cfg +++ b/tests/jsonunittests.cfg @@ -20,7 +20,7 @@ # You can contact me by mail: . # -pcp=../src/pcp1 +pcp=../pcp passwd=xxx verbose=1 diff --git a/tests/md5 b/tests/md5 index d9d8207..63556e8 100755 --- a/tests/md5 +++ b/tests/md5 @@ -1,5 +1,5 @@ #!/bin/sh file=$1 -../src/pcp1 -C $file | awk '{print $4}' +../pcp -C $file | awk '{print $4}' diff --git a/tests/meson.build b/tests/meson.build new file mode 100644 index 0000000..8e2f4cf --- /dev/null +++ b/tests/meson.build @@ -0,0 +1,54 @@ +# -*-python-*- + +# genheader statictest buffertest sample pipetest decodertest + +fs = import('fs') + +binaries = [ + 'gencheader', + 'statictest', + 'buffertest', + 'sample', + 'pipetest', + 'decodertest', + 'mangle', + 'invalidkeys', + 'pwhashes', + 'streamtest', +] + +configs = [ + 'cppunittests.cfg', + 'iotests.cfg', + 'jsonunittests.cfg', + 'keys.cfg', + 'pyunittests.cfg', + 'stresstests.cfg', + 'unittests.cfg', + 'md5', + 'jot', + 'bart.pub', + 'key-alicia-pub', + 'key-alicia-sec', + 'key-bobby-pub', + 'key-bobby-sec' +] + +foreach binary: binaries + executable( + binary, + binary + '.c', + include_directories: [pcp_inc], + dependencies: [libpcp_dep, pcp_deps], + ) +endforeach + +foreach config: configs + cp = fs.copyfile(config) +endforeach + +unittest = find_program('unittests.sh', '.') + +test('C tests', unittest, args : ['unittests.cfg']) +test('IO tests', unittest, args : ['iotests.cfg']) +test('JSON tests', unittest, args : ['jsonunittests.cfg']) diff --git a/tests/pwhashes.c b/tests/pwhashes.c index 76ba429..106244f 100644 --- a/tests/pwhashes.c +++ b/tests/pwhashes.c @@ -1,13 +1,13 @@ -#include +#include +#include #include #include -#include -#include +#include -#include "mem.h" #include "defines.h" -#include "keyprint.h" #include "key.h" +#include "keyprint.h" +#include "mem.h" struct _pw_t { char hash[65]; @@ -24,28 +24,29 @@ int main() { pw *list = NULL; pw *have = NULL; unsigned char nonce[32] = {1}; + PCPCTX *ptx = ptx_new(); - if(sodium_init() == -1) return 1; + if (sodium_init() == -1) + return 1; - for(i=97; i<126; ++i) { + for (i = 97; i < 126; ++i) { pass[0] = i; pass[1] = 0; - h = pcp_derivekey(pass, nonce); + h = pcp_derivekey(ptx, pass, nonce); - p =0; - for(t=0; t<32; ++t) { + p = 0; + for (t = 0; t < 32; ++t) { sprintf(&tmp[p], "%02x", h[t]); p += 2; } have = NULL; HASH_FIND_STR(list, tmp, have); - if(have == NULL) { + if (have == NULL) { item = ucmalloc(sizeof(pw)); memcpy(item->hash, tmp, 65); - HASH_ADD_STR( list, hash, item ); - } - else { + HASH_ADD_STR(list, hash, item); + } else { fprintf(stderr, "Error: collision found: %s!\n", have->hash); return 1; } diff --git a/tests/unittests.cfg b/tests/unittests.cfg index 6886d05..c5537e1 100644 --- a/tests/unittests.cfg +++ b/tests/unittests.cfg @@ -20,7 +20,7 @@ # You can contact me by mail: . # -pcp=../src/pcp1 +pcp=../pcp vault=v1 passwd=ech9xeiT%CuxuH1ch-is2ies1R md5msg=66b8c4ca9e5d2a7e3c0559c3cdea3d50 @@ -40,29 +40,29 @@ check_dependencies_pcp () { } check_streams_8 () { - md5=`./md5 ../COPYING` - cmd="./pipetest 8 e < ../COPYING | ./pipetest 8 d | ./md5" + md5=`./md5 ../../COPYING` + cmd="./pipetest 8 e < ../../COPYING | ./pipetest 8 d | ./md5" expect="/$md5/" check "$cmd" "$expect" "$input" } check_streams_16 () { - md5=`./md5 ../COPYING` - cmd="./pipetest 16 e < ../COPYING | ./pipetest 16 d | ./md5" + md5=`./md5 ../../COPYING` + cmd="./pipetest 16 e < ../../COPYING | ./pipetest 16 d | ./md5" expect="/$md5/" check "$cmd" "$expect" "$input" } check_streams_32 () { - md5=`./md5 ../COPYING` - cmd="./pipetest 32 e < ../COPYING | ./pipetest 32 d | ./md5" + md5=`./md5 ../../COPYING` + cmd="./pipetest 32 e < ../../COPYING | ./pipetest 32 d | ./md5" expect="/$md5/" check "$cmd" "$expect" "$input" } check_streams_64 () { - md5=`./md5 ../COPYING` - cmd="./pipetest 64 e < ../COPYING | ./pipetest 64 d | ./md5" + md5=`./md5 ../../COPYING` + cmd="./pipetest 64 e < ../../COPYING | ./pipetest 64 d | ./md5" expect="/$md5/" check "$cmd" "$expect" "$input" } @@ -284,27 +284,27 @@ check_sym_decrypt () { # # signature tests check_sign_detached_to_bobby () { - cmd="$pcp -V va -g -I README -f testsig -x a" + cmd="$pcp -V va -g -I ../../COPYING -f testsig -x a" expectfile="testsig" expect="" check "$cmd" "$expect" "$input" "$expectfile" } check_verify_detached_signature () { - cmd="$pcp -V vb -c -f testsig -I README -i $idalicia" + cmd="$pcp -V vb -c -f testsig -I ../../COPYING -i $idalicia" expect="/verified/" check "$cmd" "$expect" "$input" } check_verify_detached_signature_self () { - cmd="$pcp -V va -c -f testsig -I README" + cmd="$pcp -V va -c -f testsig -I ../../COPYING" expect="/verified/" check "$cmd" "$expect" "$input" } check_sign_armored_to_bobby () { rm -f testsig - cmd="$pcp -V va -g -I README -O testsig -x a -z" + cmd="$pcp -V va -g -I ../../COPYING -O testsig -x a -z" expectfile="testsig" expect="" check "$cmd" "$expect" "$input" "$expectfile" @@ -324,7 +324,7 @@ check_verify_armored_signature_self () { check_sign_bin_to_bobby () { rm -f testsig - cmd="$pcp -V va -g -I README -O testsig -x a" + cmd="$pcp -V va -g -I ../../COPYING -O testsig -x a" expectfile="testsig" expect="" check "$cmd" "$expect" "$input" "$expectfile" @@ -345,7 +345,7 @@ check_verify_bin_signature_self () { # # sign+encrypt tests check_sign_crypt_to_bobby () { - cmd="$pcp -V va -g -e -I README -O testsig -r Bobby -x a" + cmd="$pcp -V va -g -e -I ../../COPYING -O testsig -r Bobby -x a" expect="/Encrypted/" check "$cmd" "$expect" "$input" } @@ -572,26 +572,26 @@ check_fuzz_binary_seckey () { # checksum tests check_checksum_copying () { - cmd="$pcp -C ../COPYING" + cmd="$pcp -C ../../COPYING" expect="/$blake2/" check "$cmd" "$expect" "$input" } check_checksum_authenticated_copying () { - cmd="$pcp -x $key -C ../COPYING" + cmd="$pcp -x $key -C ../../COPYING" expect="/$blake2auth/" check "$cmd" "$expect" "$input" } check_checksum_copying_stdin () { - cmd="$pcp -C < ../COPYING" + cmd="$pcp -C < ../../COPYING" expect="/$blake2/" check "$cmd" "$expect" "$input" } check_checksum_multiple () { - cmd="$pcp -C ../COPYING ../README" - expect="/README/" + cmd="$pcp -C ../../COPYING ../../../COPYING" + expect="/../../COPYING/" check "$cmd" "$expect" "$input" } diff --git a/tests/unittests.sh b/tests/unittests.sh index 1d54e07..80cc763 100755 --- a/tests/unittests.sh +++ b/tests/unittests.sh @@ -106,13 +106,23 @@ callcheck () { cfg="$1" check="$2" +pwd=$(pwd) +base=$(basename "$pwd") + +if test "$base" != "test"; then + cd tests +fi + + +echo "PWD: $(pwd)" + if test -z "$cfg"; then echo "Usage: $0 [check]" exit 1 fi if ! test -e "$cfg"; then - echo "$cfg doesn't exist!" + echo "$cfg doesn't exist ($(pwd))!" exit 1 fi